2009-10-26 94 views
5
  1. OutofMemory异常的可能原因是什么?OutOfMemory异常

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

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

在我们的应用它是在不同的地方,如Stream.ReadToEnd()DataTable.WriteXml(Memory stream)功能。

环境的.Net C#

+1

首先,至少要提到你的问题所涉及的环境(如果有的话)。 .Net和Java至少有一个OOM例外。其次,2)这甚至不是一个恰当的问题。你在问什么?投票结束。 – sleske 2009-10-26 09:25:06

+0

1)Envoirment is .Net C# 2)为什么这个问题是不正确的 – Buzz 2009-10-26 09:49:55

+0

嗯,问题1)一个问题,但如此笼统,以至于它并没有真正有意义的答案。 2)不是问题,3)至少应该得到一个问号。请尝试使用适当的标点符号和拼写,最重要的是给出一些上下文。 – sleske 2009-10-26 10:35:59

回答

7

OutOfMemory exception内,只要到以下任何MSIL指令调用失败

  1. newobj
  2. newarr

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

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

  2. 垃圾回收器查找“垃圾”,不会使用的实例 - 哪个CANT可以被使用,因为没有其他实例指向它们。 例如,如果有一个包含实例的List类型的实例成员,GC将不会收集该列表或其实例。继续向列表添加实例可能会增加OutOfMEmory异常。

,如果你想使用以下VM参数/需要增加你的应用程序所使用的内存: 的Java youAppName -Xms128m -Xmx512m

2

无论您使用的应用程序即可以使用更多的内存。在这种情况下,您需要研究如何使内存使用更加高效。使用文件/数据库来存储您没有立即使用的数据可能是必要的。

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

如果您使用的是C#或.Net,则可以使用CLR事件探查器分析您的内存以查看它是如何使用的。 CLR Profiler

+0

有多少内存可用于应用程序如何检查? – Buzz 2009-10-26 09:48:30

+0

在32位Windows(Win7以前版本)上,虚拟内存(带有特定开关的3GB)的硬盘限制为2GB。 64位Windows可以支持8TB(Itanic上的7TB)。在分配失败之前您可以访问的实际内存可能会有所不同。 – 2009-12-10 06:16:41

2

您的应用程序使用了可用的内存,或者您有堆碎片问题。

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

在第二种情况,堆碎片中,您尝试创建一个大于堆中最大连续内存块的对象。这种情况比较少见,但在某些情况下肯定会发生。在gc运行过程中,普通堆会被压缩,但大对象堆不会。

关于大型对象堆,MSDN上有一个很好的article

编辑:我想起了另一种解决内存不足的方法。您可以尝试创建大小超过2GB的对象。即使在64位上,这也是.NET中的最大对象大小。