【发布时间】:2010-04-19 21:47:52
【问题描述】:
我在 .Net 中遇到了一些关于垃圾收集的奇怪行为。
以下程序将很快抛出 OutOfMemoryException(在 32 位、2GB 机器上不到一秒)。永远不会调用 Foo 终结器。
class Foo
{
Guid guid = Guid.NewGuid();
byte[] buffer = new byte[1000000];
static Random rand = new Random();
public Foo()
{
// Uncomment the following line and the program will run forever.
// rand.NextBytes(buffer);
}
~Foo()
{
// This finalizer is never called unless the rand.NextBytes
// line in the constructor is uncommented.
}
static public void Main(string args[])
{
for (; ; )
{
new Foo();
}
}
}
如果 rand.nextBytes 行未注释,它将无限运行,并且定期调用 Foo 终结器。这是为什么呢?
我最好的猜测是,在前一种情况下,CLR 或 Windows VMM 都懒得分配物理内存。缓冲区永远不会被写入,因此物理内存永远不会被使用。当地址空间用完时,系统崩溃。在后一种情况下,系统会在地址空间用完之前用完物理内存,触发 GC 并收集对象。
但是,这是我不明白的部分。假设我的理论是正确的,为什么地址空间不足时 GC 不触发?如果我的理论不正确,那么真正的解释是什么?
【问题讨论】:
标签: .net garbage-collection clr