A static collection is a typical source of a "memory leak by design". In .NET, you are more or less protected from the casual memory leaks, because you don't have to clean up memory after every operation you use it; the Garbage Collector (GB) takes care about it. Despite of the common believe, which is a mistake, it does not mean .NET absolutely protects you from memory leaks. It depends on what do you call a "memory leak", but if you can easily organize degradation related to consuming more and more memory in some program life cycle, when you don't give GC a chance to collect functionally unused memory, even if you only use managed memory, no unmanaged (which could be a separate source of memory leaks).
How can it be possible? Imagine you have some collection with the life time about the life time of your application. It often happens to the static collections (apparently all static objects live through the whole process life time), but it can be an instance field/property or even the a variable, if you have a function running beyond main life cycle, such as main UI application event loop. The problem appears when your application has some big life cycle repeated many times (which is always the case with UI applications) and when you use some collection which is used again and again beyond one cycle. However, this is not enough to create a leak. The leak happens when you add some objects the the collection which you don't remove by the next cycle, if you do it on a regular basis in at least some cycles. If you allow for such additions to the collection, you effectively block the objects from being garbage-collected.
You should understand, the GC can only collect objects which are rendered inaccessible by the currently executing code in your application domain. This is called
reachability. Please see:
http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29[
^],
http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29#Reachability_of_an_object[
^].
In most cases, you should get rid of static collections. From your information, I cannot see why would you think your collection had to be static; in most cases, it is not required. Major concern about static collections is threading, not so much of the danger of the memory leaks. Besides, turning the static collection into an instance field/property does not provide 100% guarantee (but usually should be done and often can solve the problem). Rather, you should guarantee clean up of the collection in each cycle or "saturation", the situation when a collection is populated but stop growing after certain point. (One example is some information obtained from reflection; if you don't allow duplicates, you collect all the reflected data you have in the application domain and the collection get saturated.)
One alternative approach is using
weak references instead of "regular" references, in case of reference objects stored in the collection. GC can still collect the objects accessible by weak references. Please see the class
System.WeakReference
:
http://msdn.microsoft.com/en-us/library/system.weakreference.aspx[
^].
See also:
http://msdn.microsoft.com/en-us/library/ms404247.aspx[
^].
With this approach, you should take care to prevent de-referencing of an object which has been garbage-collected.
Again, your information is not enough to give you the final recipe in your particular case, but I explained the principles you can utilize to analyze your application process and prevent memory leaks.
—SA