I have a C# Windows Service running on the .NET Framework 3.5 that is exhibiting a constantly growing number of GC Handles (seen using System Monitor on Windows Server 2003).
I have ensured that all resources are disposed of correctly, and have no Finalisers in my code.
The 'Large Object Heap size', and '# Bytes in all Heaps' are comparitively static, and I can see the '% Time in GC' is showing that Garbage collections are occurring.
The 'Private Bytes' counter is also increasing.
This symptom is causing my 'Memory Usage' in Task Manager to grow at around 35 MB per day, which is unacceptable as the Service is basically running a simple SELECT query against Oracle 10g and using .NET TraceSources every 5 seconds. It is probably worth mentioning that the TraceSource outputs to the Windows Event Log AND a text file using the .NET Listeners objects.
Does anyone know why the '# GC Handles' is constantly increasing, as I believe this is related to my increase in 'Memory Usage'?
OK - sorted it.
After examining the source code for the .NET TraceSource class, it appears that, by design, it owns 2 lists of WeakReferences - 1 for the TraceSource objects, and one for the Switches.
It does this to support its RefreshAll method.
I had to use Reflection to manually clear out these lists. So, I cannot use the RefreshAll method safely any more, but at least I don't have growth in Private Bytes and GC Handles any more.
To reproduce the problem, just create a whole load of TraceSource objects and close them - you can see the "leak".