Is it instantaneous after the GC runs?
I was monitoring Memory (Available MBytes) using perfmon while running an application I'm working on. As I loaded files I could see the Available MBytes going down as expected, but as I closed them it didn't go back up so I'm wondering if I am not disposing correctly or if there is something else that affects this.
When a file is loaded:
- the contents are stored in some objects
- a new instance of a UserControl is created
- a new TabPage is created
- the UserControl is added to the TabPage
- the TabPage is added to the TabControl
Reading on SO I saw that one of the most common things that can cause Memory Leaks is not unsubscribing from event handlers and so I made sure I did that in my UserControl's dispose method. I subscribe to the 'RemovingTab' event of the TabControl but the TabPages themselves have no attached handlers.
When closing a file, I remove stored instances of the objects and call dispose on both the UserControl and the TabPage. I tried running the CLR profiler (which I haven't had any experience with) and it said there was no GC runs.
Another common source of memory not being released is holding onto unmanaged resources, open files being one example.
The memory is available after the GC cleans up whatever is using it. Not every GC run results in memory being released. Any object that survives at least one GC run can end up living a long time because it's no longer in generation 0 - those could end up being around until the app actually needs more memory than is currently available to it. Large objects (larger than 85kb, as far as I remember) are stored on the large object heap which also isn't part of every GC run.
Your best bet is to look at what is actually holding the memory. Use the Visual Studio performance tools or try PerfView. Once you know what is actually holding the memory you'll be in a better position to figure out how to get it released.