我有一个.NET System.Threading.Timer计时器,每隔60秒就会打勾,并在每个滴答声中引入内存泄漏。
在计时器的每个刻度上,代码分配一个IDisposable对象(称为SocketsMessageConnector)......但我确实正确处理它。
我运行了.NET Memory Profiler,每60秒我看到一个新的SocketsMessageConnector类实例在内存中停留(所以在15分钟后,我有15个实例)。内存分析器验证实例是否已被释放,但它显示了一个以TimerCallback为根的实例,该实例以_TimerCallback为根,该查询以GCHandle为根...
这里有什么?为什么TimerCallback保持在每个定时器滴答时创建的新实例?
PS。在拍摄快照之前,分析器强制2个GC,所以我知道它实际上是泄漏而不仅仅是GC的优化。
答案 0 :(得分:7)
仅仅因为它被处理掉了,并不意味着它已被收集了垃圾。
尝试将计时器更改为每秒运行两次,然后让它运行10分钟。现在检查你的类对象中有多少仍然“在内存中挥之不去”。如果你确实有内存泄漏,你将有1200个对象。但是如果垃圾收集已经进入,那么你的收入将会大大减少 - 可能低于100。