C# System.OutOfMemoryException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1030811/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 06:33:17  来源:igfitidea点击:

System.OutOfMemoryException

c#sqlweb-services

提问by rmdussa

I have C# Client application calling Windows webservice written in WCF calling Sql Procedure and this proc give output around 1.3 million records then the C# client application keep them in memory and does all validations one by one I am getting error:

我有 C# 客户端应用程序调用用 WCF 编写的 Windows webservice 调用 Sql 程序,这个 proc 输出大约 130 万条记录,然后 C# 客户端应用程序将它们保存在内存中并进行所有验证我得到错误:

System.Exception: An exception has occurred when recalculating the balances, the transaction will be rolled back.

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()

what might be to cause this error and how to rectify it? I have checked in proc,it is running fine

什么可能导致此错误以及如何纠正它?我已经检查了 proc,它运行良好

采纳答案by Jeff Meatball Yang

It seems like you are trying to initialize a generic List of some type, and in doing so, running out of memory.

似乎您正在尝试初始化某种类型的通用列表,并且这样做会耗尽内存。

The procedure itself may be successful, but may also be returning many, many rows.

该过程本身可能会成功,但也可能会返回许多行。

You may want to step through your code and inspect the results of the query before initializing the List object.

在初始化 List 对象之前,您可能希望单步执行代码并检查查询结果。

Without more details, I'm afraid I can't help debug more.

没有更多细节,恐怕我无法帮助调试更多。

Edit:

编辑:

You will need to handle the results of the stored procedure in batches. You can still use a SqlDataReader, but I would suggest making a List with a max capacity of something relatively small, like 1000, and read from the SqlDataReader until you have filled the List... then clear the list and start reading again:

您将需要批量处理存储过程的结果。您仍然可以使用 SqlDataReader,但我建议创建一个最大容量相对较小的列表,例如 1000,然后从 SqlDataReader 读取,直到您填满列表...然后清除列表并再次开始阅读:

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);
  }
}

回答by Lukas ?alkauskas

Also you can read this article

你也可以阅读这篇文章

“Out Of Memory” Does Not Refer to Physical Memory

“内存不足”不是指物理内存

回答by Perica Zivkovic

You can also use MemoryFailPoint class to check do you have enough memory before allocating big arrays, lists or other big objects.

您还可以使用 MemoryFailPoint 类在分配大数组、列表或其他大对象之前检查您是否有足够的内存。

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

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

nice blog post about OutOfMemory

关于 OutOfMemory 的好博文

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

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

回答by Rad

Just a question -- do you have to load all the 1.3 million rows into memory? That's a lot of data even if each row is say 1KB. Small wonder your application is struggling to execute.

只是一个问题——您是否必须将所有 130 万行加载到内存中?即使每一行都是 1KB,这也是很多数据。难怪您的应用程序难以执行。

Is it possible to refactor your application to load a subset of the data?

是否可以重构您的应用程序以加载数据的子集?