2

我有正在处理大量数据的应用程序,并且我正在监视它的 .NET 内存性能计数器。基于性能计数器,所有堆中的#Bytes 正在缓慢增长(每 12 小时大约 20MB)。还收集了所有 3 代(每秒 gen0 几次,大约每秒一次 gen1,大约每分钟一次 gen2) - 但它不会阻止所有堆中的 #Bytes 缓慢增长。但是,如果我明确运行:

GC.Collect();
GC.WaitForPendingFinalizers();

它将收集所有额外消耗的内存。(例如,如果在 12 小时后运行,堆占用空间会减少 20MB)。我还试图GC.Collect通过 sos 和 sosex 检查转储(在运行之前) - 大多数挂在周围的物体都是无根的。

为什么隐式垃圾收集运行(由性能计数器显示)收集内存,显式GC.Collect()调用会这样做?

编辑:

我忘了提到那些没有根的对象没有实现 IDisposable - 因此它们应该在该特定代的第一次 GC 运行期间被回收(换句话说 - 错误的 Dispose() 方法和死锁终结器的潜在问题是在这里毫无疑问。但指出斯蒂芬和罗伊指出了这种可能性)

4

1 回答 1

3

垃圾收集器实际上非常聪明。如果不需要,它不会收集内存,这为其提供了一些优化灵活性。

它保持打开恢复需要完成但尚未完成的对象的选项。只要不需要内存,垃圾收集器就不会强制完成,以防万一它可以复活那些对象。

于 2013-06-10T09:31:18.920 回答