不同机器上的垃圾收集器性能

时间:2010-12-20 13:19:22

标签: .net garbage-collection

我有一个大内存消耗.NET 2.0应用程序。通常情况下,GC可以很好地处理内存清理。 但是,我有一个案例,应用程序安装在2个不同的机器上,一个有2GB的内存,一个有3GB的内存。在3gb的内存中,它会因Out Of Memory异常而崩溃,而在2gb内则它会失败。 .net运行时在两台机器中都是相同的,并且应用程序安装也是相同的。 当内存更多时,启动Grabage Collector的触发器可能不会按时提升?

2 个答案:

答案 0 :(得分:3)

RAM的数量 nothing 与.NET程序可用的内存量有关。所有现代操作系统都提供虚拟内存。在Windows上,程序可用的典型虚拟内存量略小于2千兆字节。有一个特殊的启动选项(/ 3GB),增加到3千兆字节,代价是从操作系统中取出可寻址的内存。它在大多数现代机器上不再起作用,视频卡往往会占用太多可寻址的物理内存。由于这个原因,实际上不可能达到不到2GB。

如果机器运行的是64位操作系统,那么如果代码在x86模式下运行,您将接近4千兆字节。 x64模式下的虚拟内存大小,仅受页面文件的最大大小限制。

这些虚拟内存大小完全独立于计算机上安装的实际RAM量。如果你的RAM比可寻址的虚拟内存空间少,这在15年前很常见,那么就可以调用所谓的“分页文件抖动”。您会看到操作系统尝试提供足够的可用RAM以满足程序同时使用过多虚拟内存的需要。它在RAM和页面文件之间交换数据。这可能会严重降低机器速度,在耗尽内存之前就会没有耐心。

OutOfMemoryException告诉您程序耗尽了可寻址的虚拟内存。最典型的原因并不是实际上完全耗尽了所有的地址空间,它的空洞已经足够大,无法容纳你想要分配的对象。虚拟内存可能会碎片化。 SysInterals的VMMap实用程序可以让您深入了解程序的虚拟内存是如何分配的。

虚拟内存耗尽很难处理,它本质上是一个无法从中恢复的异步异常。除了执行像加载位图之类的操作之外,需要大量(非托管)内存的对象类型因此几乎总是找不到足够大的漏洞。一般来说,你的程序永远不会比使用一半的可用空间更接近。这通常不困难,一个千兆字节是很多内存。当程序的需求基本超出该限制时,您必须为程序指定64位操作系统要求。一个两百美元的解决方案。

答案 1 :(得分:0)

如果有东西可以收集,你会发现GC会起作用。听起来你在代码中有一些未知的内存泄漏导致GC忽略了对象,换句话说,根据运行时它们不适合收集。

你使用了很多活动吗?

如果你认为GC没有收集有效的对象,你可以强制收集(强制防御:几乎不需要调用GC.Collect而不是内存分析工具的替代品):

GC.Collect(GC.MaxGeneration)

http://msdn.microsoft.com/en-us/library/y46kxc5e.aspx

如果对象已准备好收集,则会在此处收集它们。我怀疑正在保持对对象的引用,停止GC。

更新:当然在盒子外面,机器内存耗尽不一定是因为你的程序。与2Gb计算机相比,这台其他计算机是否同时运行了更多的东西?