C# IDisposable And Garbage Collector

Garbage collector manages managed and unmanaged resources. For managed resources GC will take care of that. 

But for unmanaged resources it depends on users to clean up otherwise it stays in memory till the application closes or explicitly GC is called.

Managed Resources

We don’t have to handle this but some resources which are managed but internally wrapped unmanaged resources, we have to release this. 

Ex. DbConnection, Files, Stream

Unmanaged Resources

We hardly use it, but if we use then need to release it. 

Ex. DllImport, IntPtr

So .Net framework provides IDisposable for these resources for which GC can’t dispose but relies on you to dispose such resources to optimize memory better way.

How GC works

GC has group like Generation0, Generation1, Generation2

GC runs and checks objects that are no longer in use and dispose them, but those who have reference and live connection move to Gen1, GC does not frequently check Gen1, but again when checks in Gen1 then again dispose those not in use and move objects to Gen3 which are in use.

Stack generally stores reference data and pointers.

Heap stores actual data.

Ways to implement IDisposable

When we use an instance of any IDisposable class then we have to implement IDisposable.

Ex:

Public class Custom: IDisposable {
    Private SqlConnection _connection; //This is instance of IDisposable
    Private _disposed = false;
    Public void Dispose() {
        Dispose(true);
        GC.SupressFinalize(this); // It indicates GC that this resource clean up and not need to finalize. This helps GC to not run to clean up this resource.
    }
    Protected virtual Dispose(bool disposing) {
        if (!_disposed) {
            if (_connection != null) {
                _connection.dispose(); //Release managed resources.            
                _connection = null;
            }
        }
        //Release unmanaged resource
        _disposed = true;
    }
}

Now when you use the instance of Custom in using block, after using block it automatically calls Dispose method of Custom.

using(var custom = new Custom()) {
    // call methods on custom class
} // Now here at this point after using block gets call it is calling Dispose method on Custom and releasing resources.

Static code analysis is a tool to identify IDisposable issues in a project.

To Enable it in .csproj file add below line:

<AnalysisMode>AllEnabledByDefault</AnalysisMode>

Build project and you will find warnings of IDisposable issue.

To better understand when to dispose you need domain knowledge of application and lifetime of objects.

Some sample examples are,

var custom = new Custom();
try {
    // custom method calls.
} finally {
    custom.Dispose();
}
using
var inputStream = File.openRead("filepath");
using(var outputStream = File.Create("targetPath")) {
    inputStream.CopyTo(outputStream);
}


Similar Articles