Dev*_*inB 8 .net garbage-collection large-object-heap
在我的应用程序中,有一个特定的时间,一次释放大量的大对象.那时我想特别针对大对象堆(LOH)进行垃圾收集.
我知道你不能这样做,你必须打电话,GC.Collect(2)因为只有在进行第2代收集时才会在LOH上调用GC.但是,我在文档中读到,调用GC.Collect(2)仍然会在第1代和第0代运行GC.
是否可以强制GC 仅收集第2代,而不包括第1代或第0代?
如果不可能,是否有理由以这种方式设计GC?
Jor*_*ren 14
这是不可能的.GC的设计使得第2代集合始终也可以收集第0代和第1代.
编辑:在GC开发人员的博客上找到了这个来源:
Gen2 GC需要一个完整的集合(Gen0,Gen1,Gen2和LOH!即使在LOH中没有空间而没有触发GC的情况下,每个Gen2 GC都会对大型对象进行GC操作.请注意,没有GC仅收集大型物品.)比年轻一代的藏品需要更长的时间.
编辑2:来自同一个博客的高效使用GC 第1部分和第2部分显然Gen0和Gen1集合与Gen2集合相比是快速的,因此对我而言,只有做Gen2才会有很大的性能优势.可能有一个更根本的原因,但我不确定.也许答案出现在该博客的一些文章中.
由于所有新分配(大型对象除外)总是在Gen0中,因此GC设计为始终从指定的一代及以下进行收集.当你打电话时GC.Collect(2),你告诉GC从Gen0,Gen1和Gen2收集.
如果你确定你正在处理许多大对象(在分配时足够大以放置在LOH上的对象),最好的选择是确保在完成后将它们设置为null(在VB中为Nothing)跟他们.LOH分配尝试智能和重用块.例如,如果您在LOH上分配了一个1MB的对象,然后将其丢弃并将其设置为null,那么您将留下1MB的"空洞".下次你在LOH上分配1MB 或更小的任何东西时,它将填入那个洞(并继续填充它,直到下一个分配太大而不适合剩余空间,此时它将分配一个新区块.)
请记住,.NET中的代数不是物理内容,而是逻辑上的分离以帮助提高GC性能.由于所有新分配都在Gen0中,因此始终是第一代收集.每个运行的收集周期,在收集后幸存的较低代的任何东西都被"提升"到下一代(直到达到Gen2).
在大多数情况下,GC不需要超越收集Gen0.GC的当前实现能够同时收集Gen0和Gen1,但是在收集Gen0或Gen1时它无法收集Gen2.(.NET 4.0大大放宽了这个约束,并且在大多数情况下,GC能够收集Gen2,而Gen0或Gen1也被收集.)
| 归档时间: |
|
| 查看次数: |
7837 次 |
| 最近记录: |