【译】让垃圾回收器高效工作(四)
这篇文章我们来谈谈垃圾回收器和程序的虚拟内存、物理内存之间的关系。再谈谈怎样判断你的托管堆是否是健康的;为什么在机器还有大量内存的情况下程序会抛出OutofMemoryException。 垃圾回收和物理内存虚拟内存之间的关系: 如果你对这个话题已经了如指掌,请跳过这一段。 GC需要分配段,有关段的解释请参考《 让垃圾回收器高效工作(一) 》。GC调用VirtualAlloc来分配段空间。这意味着如果你的进程中没有足够的连续空间,分配就失败了。这是一种GC抛出OutOfMemeoryException的合法的情况(精确的说,GC没有抛出异常,抛出异常是执行引擎干的,GC只是在分配失败时返回了NULL)。 经常有人问我这样的问题:“为什么我程序的托管堆只使用了X MB的内存,运行时抛出了OutofMemoryException呢?” 其中XMB比2GB小得多。 记住在.Net程序中有一些内存不是GC消耗的。GC和其他一些东西一样是在竞争虚拟内存的空间。比如:你进程中载入的模块需要占用虚拟内存;有些模块直接调用本机代码分配内存也会消耗虚拟内存(VirtualAlloc,HeapAlloc,C++的new等等)。CLR本身也会有些不通过GC分配消耗的内存,比如jitted代码,一些CLR需要的数据结构等等。通常CLR需要的内存是相当小的。你可以通过SOS的