I have a .NET System.Threading.Timer timer that ticks every 60 seconds and introduces a memory leak on each tick.
At each tick of the timer, the code allocates an IDisposable (called SocketsMessageConnector) ... but I am disposing correctly.
I started the .NET Memory Profiler and every 60 seconds I see a new instance of the SocketsMessageConnector class that lingers in memory (so after 15 minutes I have 15 instances). The memory profiler checks to see if the instance is actually hosted, but it shows the instance embedded in TimerCallback, which is embedded using _TimerCallback, which is embedded in GCHandle ...
What is here? Why is TimerCallback holding onto a new instance created with every timer?
PS. The profiler forces 2 GCs to the snapshot, so I know this is really a leak, not just a GC optimization.
Jeff
source share