If memory consumption happens in the unmanaged code called by your managed code, GC has no way of knowing that your small managed object has big memory footprint.  For example, your code might call some legacy API, which allocates memory, and your object is holding on to it until it’s destroyed.

 

When GC decides when to do garbage collection, it takes into account the size of the allocated memory.  Since it doesn’t know about the large underlying allocations, it things your object is small…  may be too small to bother to collect at this time even if nobody is referencing the object any longer.  To “hint” that your object is worth collecting, so the Dispose method is called and the unmanaged memory is freed (by your well written code), you may want to call GC.AddMemoryPressure(size), where the size is your estimated memory size of the memory you’re holding on to.  E.g. if the unmanaged code read the contents of a file and is holding on to it, it may be the size of that file…

 

Make sure to call GC.RemoveMemoryPressure(size) after the object is freed, so GC returns to it’s normal collection strategy.