我有处理大量数据的应用程序,我正在监视它的.NET内存性能计数器。 基于性能计数器,All Heaps中的#Bytes正在缓慢增长(每12小时约20MB)。 所有3代也被收集(gen0每秒几次,gen1大约每秒一次,gen2大约每分钟一次) - 但它并不能阻止All Heaps中的#Bytes慢慢增长。 但是如果我明确地运行:
GC.Collect();
GC.WaitForPendingFinalizers();
它将收集所有额外消耗的内存。 (例如,如果在12小时后运行,则堆积占用量下降20MB)。
我还试图通过sos和sosex检查转储(在运行GC.Collect
之前) - 并且大部分闲置的对象都是无根的。
为什么隐式垃圾收集运行(由性能计数器显示)收集内存,显式GC.Collect()
调用呢?
修改
我忘了提到仍然无法挂起的对象没有实现IDisposable - 所以它们应该在GC的第一次运行期间回收(换句话说 - 错误的Dispose()方法的潜在问题和死锁的终结者在这里是不可能的。但是指出斯蒂芬和罗伊指的是这种可能性)
答案 0 :(得分:3)
垃圾收集器实际上非常聪明。如果不需要,它不会收集内存,这为它提供了一些优化灵活性。
它保持打开复活选项,这些选项需要最终确定但尚未最终确定。只要不需要内存,垃圾收集器就不会强制终结,以防万一它可以恢复这些对象。