【发布时间】:2011-12-20 21:14:00
【问题描述】:
白天我在我们的 Windows 服务中看到了很多 gen 2 集合。
GC 什么时候决定进行全量收集而不是只收集 Gen1 和 Gen0 还是只收集 Gen0?
【问题讨论】:
-
可能是在感到释放一些内存的压力时。也许当系统空闲时。只是猜测。
白天我在我们的 Windows 服务中看到了很多 gen 2 集合。
GC 什么时候决定进行全量收集而不是只收集 Gen1 和 Gen0 还是只收集 Gen0?
【问题讨论】:
阅读http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx 和链接文章了解更多信息。通常,“必要时”会收集 gen2。
大对象堆 (LOH) 可能会导致 Gen2 收集过多。当 LOH 被填满时,它将触发一个完整的收集。如果您的应用程序分配和释放大量大型对象(80K 或更大),那很可能是您的问题。
见CLR Inside Out: Large Object Heap Uncovered。
还可以考虑在您的服务中使用服务器垃圾收集器。它通常会提供更好的性能(更少的集合)。将此添加到您的 app.config 文件中:
<configuration
<runtime>
<gcServer enabled="true"/>
</runtime>
</configuration>
【讨论】:
当满足以下条件之一时,通常会触发一个集合(在任何一代下)
我可能还缺少另一种情况,但通常就是这样。第一个是通常开始收集的东西,考虑到收集 G2 比 G0 (相对)更昂贵,你看到的更少。
解决评论中的问题:
每一代都有一个阈值,当命中时会触发一个集合。 Gen0 可能是 5mb,当它被填满时会被触发。 GC运行后,如果你还有里面有5mb,我相信它会增加限制。如果没有,那么每次分配都会触发一个集合,你就会遇到问题。 Gen2 可能为 20mb(注意我在这里编造数字),同样的逻辑也适用于那里。
对于一个教科书的例子,让我们看一个简单的场景。
完整的 GC 很昂贵,而且我已经看到几天没有发生任何事情。当然这是在具有 >64GB 可用内存的系统上,并且不需要它。
【讨论】: