What Needs to Be Disposed?
If you’re like me, you just do as the .NET FCL (Framework Class Library) documentation tells you and use a using
statement to properly dispose SqlConnection
or FileStream
.
Even though the CLR (Common Language Runtime) has a sophisticated garbage collector, memory leaks can and do happen.
How can you be more confident in what you need to Dispose
to prevent memory issues?
Why do We Dispose?
We want to make sure we dispose any resource that is not part of the managed heap. The managed heap is that safe place where the garbage collector lives. Pointers to all of the objects you new
up are going to be in the managed heap, and will eventually be garbage collected.
Some classes use resources that can’t do their thing with memory alone. They wrap a native resource that the garbage collector doesn’t know about. While these wrapper objects live in the managed heap, the native resources they wrap do not. They can leak. They are what we need to pay attention to.
Not the Same as GC’ing
When we say we want to dispose native resources, that doesn’t necessarily mean we want to reclaim managed memory like the garbage collector does. The garbage collector is the only thing that should reclaim memory from the managed heap. The garbage collector is going to be much better than you at knowing if a managed object is not needed anymore.
”…calling
Dispose
does not delete the managed object from the managed heap. The only way to reclaim memory in the managed heap is for a garbage collection to kick in” - Richter, 2012
Our concern is preventing an object in the managed heap from being garbage collected before it releases any native resources it is wrapping.
Things We Should Dispose
Here are some examples of resources that need to be disposed before their wrappers are GC’d:
- file handles
- database connections
- network connections
- sockets
- mutexes
- bitmaps
- windows
There are FCL classes that wrap these resources and also implement IDisposable
. For those, we’re in good shape. Just make sure you follow the rules when you’re using them or wrapping them with your own types.
One way to find some of the FCL classes that implement IDisposable
is to search the Roslyn-based .NET Framework Reference Source for the method Dispose
.
Summary
In order to answer the question What Needs to be Disposed? we took a quick look at Why do We Dispose?. An issue that we want to be aware of is when a class uses a native resource. The native resource is not going to be seen by the garbage collector.
We also want to let the garbage collector do its job, because it does a good job. It doesn’t need to be told what to do all the time.
Finally, we looked at a way we might be able to find a few examples in the FCL of classes we want to dispose by searching the .NET Framework Reference Source for the Dispose
method.
Hopefully this was insightful, I definitely learned a lot. Feel free to contact me if you’d like to riff on the subject, sign up for my newsletter (if you haven’t already), or discuss below!
Sources:
- Richter, Jeffrey. CLR via C#, 4th Edition. Microsoft Press, 2012. ISBN 9780735667457
- De Smet, Bart. C# 5.0 Unleashed. Sams, 2013. ISBN 9780672336904
- MSDN. The Dispose Pattern
- MSDN. Cleaning Up Unmanaged Resources
- MSDN. Object.Finalize Method ()
- MSDN. SafeHandle Class
- Stack Overflow. Proper use of the IDisposable interface