OutOfMemory异常

时间:2009-10-26 09:09:48

标签: c# out-of-memory garbage-collection

  1. OutofMemory例外的可能原因是什么。

  2. 内存分配应由GC处理。

  3. 分配了多少内存/可用于正常的.NET / C#应用程序

  4. 在我们的应用程序中,它来自Stream.ReadToEnd()DataTable.WriteXml(Memory stream)函数等不同的地方。

    环境是.Net C#

4 个答案:

答案 0 :(得分:7)

只要对以下任何MSIL指令的调用失败,就会发生OutOfMemory exception

  1. newobj
  2. newarr
  3. 其中基本上是在堆中分配新内存的操作,在你的情况下,Stream.ReadToEnd显然在内部分配字节数组以在内存中加载流,所以如果文件大到足以打破进程就会抛出这个异常。

答案 1 :(得分:2)

您使用的内存比应用程序可用的内存多。在这种情况下,您需要了解如何提高内存使用效率。使用文件/数据库存储您不会立即使用的数据可能是必要的..

或者,您有内存泄漏。在这种情况下,您需要在不再使用时删除对内存的引用,以便GC可以释放内存。

如果您使用的是C#或.Net,则可以使用CLR Profiler分析您的内存,以了解它的使用方式。 CLR Profiler

答案 2 :(得分:2)

您的应用程序已用尽可用内存,或者您遇到堆碎片问题。

在第一种情况下,您已经创建了足够的对象来占用所有内存,但您仍然可以引用它们,因此垃圾收集器无法清除它们。

在第二种情况下,堆碎片,您正在尝试创建一个比堆中最大的连续内存块大的对象。这种情况更为罕见,但在某些情况下肯定会发生。正常堆将在gc运行期间被压缩,但是大对象堆不会。

MSDN上有关于大对象堆的好article

编辑:我记得另一种失去记忆的方法。您可以尝试创建大小超过2GB的对象。即使在64位上,这也是.NET中的最大对象大小。

答案 3 :(得分:1)

  1. 假设您的应用中最多可以使用10MB内存。您创建一个新的List并添加它对象实例。现在让我们说每个对象实例“重量”1MB。因此,前10个实例将添加没有问题,但第11个实例将抛出OutOfMemoryException,因为在使用所有已分配内存(10MB)的前10个实例之后。

  2. 垃圾收集器查找“垃圾”,不会使用的实例 - 可以使用哪个实例,因为没有其他实例指向它们。 例如,如果具有包含实例的List类型的实例成员,GC将不会收集List也不会收集实例。继续向列表中添加实例,可以使用OutOfMEmory Exception。

  3. 如果您希望/需要增加应用使用的内存,请使用以下vm参数: Java youAppName -Xms128m -Xmx512m