GC何时决定收集第2代?

Pio*_*rak 8 .net garbage-collection

在白天,我在Windows服务中看到了很多第2代集合.

GC何时决定进行完全收集而不是仅收集Gen1和Gen0或仅收集Gen0?

Jim*_*hel 9

有关更多信息,请阅读http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx和链接的文章.通常,gen2是在"必要时"收集的.

可能导致过多Gen2集合的一件事是大对象堆(LOH).当LOH被填满时,它将触发完整的收集.如果您的应用程序分配并释放大量大型对象(80K或更大),那很可能是您的问题.

请参阅CLR Inside Out:大对象堆未覆盖.

还要考虑在服务中使用服务器垃圾收集器.它通常会提供更好的性能(更少的集合).将其添加到app.config文件中:

<configuration
   <runtime>
      <gcServer enabled="true"/>
   </runtime>
</configuration> 
Run Code Online (Sandbox Code Playgroud)

  • @Peri:不,服务器模式不是默认模式.使用多核时,并发GC是默认值,但它仍然是客户端GC.如果您需要服务器GC,则必须在app.config文件中说明.另外,您确定不分配大对象吗?在64位系统上,只包含10,000个项目的列表将需要大于80千字节的后备阵列. (2认同)

小智 5

通常,当满足以下1个时,触发(在任何一代下)收集

  • 分配超过阈值.我认为这是基于当前需求的动态.任何人都可以确认/否认吗?
  • 记忆力低下
  • 它通过GC.Collect()调用

可能还有另一种我不知道的情况,但通常就是这样.第一个是通常开始收集的东西,而且相对来说,收集G2比G0更贵,你看到的更少.


要解决注释中的问题:
每一代都有一个阈值,当命中时将触发一个集合.Gen0可以是5mb,并且在填充时将被触发.GC运行后,如果你还有 5mb,我相信它会增加限制.如果不是每个分配都会触发一个集合,那么你就有问题了.Gen2 可能是20mb(注意我在这里编号)并且在那里应用相同的逻辑.

对于教科书示例,让我们看一个简单的场景.

  1. 新的应用程序分配对象,所有都放在Gen0,总共3MB的数据.(情况并非总是如此,但假装是这样)
  2. GC命中,其中1 MB移至G1,其余部分被清除.
  3. G0现在是免费的,G1中有1MB.
  4. 创建了更多对象,并且发生了更多GC.过了一会儿G1充满了,有些人搬到了G2.
  5. 物体保持在那里直到G2满,然后如果不使用它们就会被清洁.如果仍然引用某个对象,它将保留在G2中,直到可以清除它为止.

一个完整的GC是昂贵的,我已经看到几天没有发生.当然,这是在一个具有> 64GB ram的系统上,并且没有必要.