.NET生成0堆大小

use*_*808 15 .net garbage-collection

是否可以在.NET中设置第0代堆的最小大小?

我有一个下面的sistuation.我有一个函数,分配大约20-30 MB的1KB对象,对它们做一些事情,然后终止,让所有分配的对象都被GC编辑.现在,在性能监视器中,我可以看到第0代堆大小是5-6 MB,这还不足以接受我需要的所有20-30 MB的对象.当我开始分配时,gen0 GC开始运行,并且因为需要所有对象,所以它们将它们提升为gen1.GC下次开始运行时,这些对象将在gen2中升级.所以最终大约15MB的对象最终进入gen2堆.根据我的逻辑,这些是临时对象,绝不应该在gen2堆中结束.我相信问题在于gen0堆大小的大小.但我不确定.我知道在Java中有可能设置最小的代数堆.在.NET中有这样的方式吗?

Bri*_*sen 8

不同代的大小是一个实现细节,我不知道有任何方法可以为.NET应用程序调整它.如果我的内存正确地为我提供了代码0和1共享一个单独的段,在Win32中是16 MB,所以如果你创建了很多对象,如果它们仍被引用,其中一些将被提升为更高代(如同你描述).

我想限制第0代大小的想法是确保g0集合便宜.如果第0代可以增长到任何规模,您的整体表现很可能会受到影响.

编辑:我相信杰弗里里希特的书有一些关于此的细节,所以你可能想要检查出来.

编辑2:里希特州(第502-507页),第0代的初始预算为256 KB,第1代的初始预算为2 MB.但是,这不是一代人的规模.预算会根据需要进行调整,并根据应用程序的内存使用量增长和缩小.

然而,Joe Duffy的Professional .NET Framework 2.0指出,ephermal世代(即gen 0和1)共享一个段,通常为16 MB(p.117).只有第2代允许根据需要增长(我认为LOH也可以根据需要增长,但我不清楚这一点).

  • Gen 0 为 256KB(适合 cpu 的 l2 缓存) Gen1 2MB Gen2 10MB 根据 Richter 的第二版书籍。当然,这些可能会发生变化...... (2认同)

And*_*are 3

您确定不再引用这些对象吗?GC非常擅长根据应用程序的需求调整自身,并且不会将对象提升到第 2 代,除非您在某处拥有这些对象的根。

我认为,如果您弄清楚这些根在哪里,并确保您确实不再在任何地方引用这些对象,那么 GC 将开始释放这些对象的内存,并且永远不会将它们提升到第 1 代,更不用说第 2 代了。此外,如果您这样做那么 GC 将检测到您需要更大的第 0 代,并将代表您增加堆的大小。