Understanding the scenario

We were working on a Windows Service for a large US bank when we discovered that there are potential issues while using Static Classes in .NET

We defined objects in a Static Dictionary object as:-

public static Dictionary<Int64, Student> StudentCollection =
               new Dictionary<long, Student>();

and added over 10,000 Student objects in it. At regular intervals of 5 seconds, we triggered a clean-up process :-

            lock (_lockObject)

An ideal/expected output would be that GC would collect the released 10,000 Student objects and hence the number of objects in heap would reduce at every 5 seconds.  But this was not true!

Much to our surprise, there was a constant ramp-up in the Gen-2 objects (observed in PerfMon.) Later on making the collection non-static, we achieved the expected results.

A quick conclusion:-

GC does not collect static objects.

Detailed analysis

Static variables/objects live for duration of the application i.e. they live in Application Domain.  Hence, they are not subject to Garbage Collection. For each static field there is one copy per-appdomain – each appdomain can have a different value. The static variable itself is not garbage collected – it is just a memory location that contains a reference to an object. Static fields are considered to be GC roots, so any references in them will not be garbage collected as long as the field contains that references it. If you change the field to point to a new reference or set the field value to null then the object whose reference was stored there becomes eligible for collection.

For more read: http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory_401282006141834PM/csharp_memory_4.aspx?ArticleID=411a0c5c-a0f6-4de2-8a17-e861d5aecd87