System.OutOfMemoryException - PullRequest
       5

System.OutOfMemoryException

1 голос
/ 23 июня 2009

У меня есть клиентское приложение C #, вызывающее веб-сервис Windows, написанное на WCF, которое вызывает процедуру Sql, и этот процесс выдает около 1,3 миллиона записей, затем клиентское приложение C # хранит их в памяти и выполняет все проверки один за другим. Я получаю ошибку:

System.Exception: исключение имеет произошло при пересчете остатки, сделка будет откат.


System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
   at System.Collections.Generic.List`1.set_Capacity(Int32 value)
   at System.Collections.Generic.List`1.EnsureCapacity(Int32 min)
   at PitToPort.DataLayer.StockpileData.StockpileProfile.CreateStockpileProfileQualityFromAllPartialMovements()
   at PitToPort.DataLayer.StockpileRecalc.Recalc.CreateSP_FOFO_FOLO_NegTransaction(Int32 modelID, StockpileProfile currentStockpileProfile, TransactionsRow drTransactions)
   at PitToPort.DataLayer.StockpileRecalc.Recalc.CreateBalanceFOLO_FOFO_TWAA(TransactionsRow[] drTransactionsRows, Int32 modelID, StockpileProfileList stockpileProfileList)
   at PitToPort.DataLayer.StockpileRecalc.Recalc.CreateBalances()
   at QMastor.PitToPort.StockpileRecalculationBL.RecalcService.CreateBalances()

что может быть причиной этой ошибки и как ее исправить? Я проверил в proc, он работает нормально

Ответы [ 4 ]

4 голосов
/ 23 июня 2009

Похоже, вы пытаетесь инициализировать общий список какого-либо типа, и при этом не хватает памяти.

Сама процедура может быть успешной, но также может возвращать много-много строк.

Возможно, вы захотите пройтись по своему коду и проверить результаты запроса перед инициализацией объекта List.

Боюсь, я не смогу больше отлаживать без подробностей.

Редактировать:

Вам нужно будет обрабатывать результаты хранимой процедуры партиями. Вы по-прежнему можете использовать SqlDataReader, но я бы предложил создать список с максимальной емкостью, относительно небольшой, например 1000, и читать из SqlDataReader до тех пор, пока вы не заполните список ... затем очистите список и начните чтение снова: 1011 *

SqlDataReader dr = cmd.ExecuteReader(); // where cmd is a SqlCommand

List<SomeType> items = new List<SomeType>(1000);

while(dr.Read()) {
  // read the values for the row
  SomeType obj = new SomeType(dr["id"], dr["value"], ...);

  // add the object to the list
  items.Add(obj);

  // when the list is full, process it, and create a new one.
  if(items.Count >= 1000) {
    Process(items);
    items = new List<SomeType>(1000);
  }
}
2 голосов
/ 23 июня 2009

Просто вопрос - нужно ли загружать все 1,3 миллиона строк в память? Это много данных, даже если каждая строка, скажем, 1 КБ. Неудивительно, что ваше приложение не может быть выполнено.

Возможно ли реорганизовать ваше приложение для загрузки подмножества данных?

1 голос
/ 23 июня 2009

Вы также можете использовать класс MemoryFailPoint, чтобы проверить, достаточно ли у вас памяти перед выделением больших массивов, списков или других больших объектов.

http://msdn.microsoft.com/en-us/library/system.runtime.memoryfailpoint.aspx

хороший пост в блоге об OutOfMemory

http://blogs.msdn.com/ericlippert/archive/2009/06/08/out-of-memory-does-not-refer-to-physical-memory.aspx

0 голосов
/ 23 июня 2009

Также вы можете прочитать эту статью

«Недостаточно памяти» не относится к физической памяти

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...