IDisposable and GC

My assumption is that if I implement IDispose on an object, I can explicitly ‘destruct’ it as opposed to waiting for the garbage collector to do it. Is this correct?

The garbage collector automatically releases the memory allocated to a managed object when that object is no longer used. However, it is not possible to predict when garbage collection will occur. Furthermore, the garbage collector has no knowledge of unmanaged resources such as DB connections, or open files and streams.  Dispose is not about memory management, it’s about unmanaged resource management

IDisposable has nothing to do with freeing memory. IDisposable is a pattern for freeing unmanaged resources.

The GC will only run when it determines the need to (called memory pressure) and then (and only then) will it deallocate memory for unused objects and compact the memory space.

You could call GC.Collect() but you really shouldn’t unless there is a very good reason to (which is almost always “Never”). When you force an out-of-band collection cycle like this you actually cause the GC to do more work and ultimately can end up hurting your applications performance. For the duration of the GC collection cycle your application is actually in a frozen state…the more GC cycles that run, the more time your application spends frozen.

 

When you are using unmanaged resources such as handles and database connections, you should ensure that they are held for the minimum amount of time, using the principle of acquire late and release early. Objects such as database connections or file handlers should be released as soon as possible, instead on relying on garbage collection. For that you should implement IDisposable interface, and release your resources in the Dispose() method. Use the Dispose method of this interface to explicitly release unmanaged resources in conjunction with the garbage collector.  The consumer of an object can call Dispose() method when the object is no longer needed. The garbage collector automatically releases the memory allocated to a managed object when that object is no longer used.

 

A finalizer (aka destructor) is part of garbage collection (GC) – it is indeterminate when (or even if) this happens, as GC mainly happens as a result of memory pressure (i.e. need more space). Finalizers are usually only used for cleaning up unmanaged resources, since managed resources will have their own collection/disposal.

 

Hence IDisposable is used to deterministically clean up objects, i.e. now. It doesn’t collect the object’s memory (that still belongs to GC) – but is used for example to close files, database connections, etc.

 

Do not add a finalizer to your class unless you really, really need one. If you add a finalizer (destructor) the GC has to call it (even an empty finalizer) and to call it the object will always survive a gen 1 garbage collect. This will impede and slow down the GC.

 

It is not uncommon for an IDisposable object to also have a finalizer. In this case, Dispose() usually calls GC.SuppressFinalize(this), meaning that GC doesn’t run the finalizer. A Dispose method should call the GC.SuppressFinalize() method for the object of a class which has destructor because it has already done the work to clean up the object, then it is not necessary for the garbage collector to call the object’s Finalize method.

 

http://csharp.2000things.com/tag/dispose/

http://msdn.microsoft.com/en-us/library/system.idisposable.aspx

http://gregbee.ch/blog/implementing-and-using-the-idisposable-interface

 

 

 

==================================================================

 

Using calls Dispose() after the using-block is left, even if the code throws an exception. We need to implement IDipose interface to use Using statement on that class.

 

So you usually use using for classes that require cleaning up after them, like IO. When we use the using statement, we don’t need to explicitly dispose of the object in the code, the using statement takes care of it.

 

So, this using block:

 

using (MyClass mine = new MyClass())

{

mine.Action();

}

 

would do the same as:

 

MyClass mine = new MyClass();

try

{

mine.Action();

}

finally

{

if (mine != null)

mine.Dispose();

}

Using using is way shorter and easier to read.

====================================================

 

How to dispose a class in .net?

 

Inside a .NET process, there are two kinds of resource — managed and unmanaged. “Managed” means that the runtime is in control of the resource, while “unmanaged” means that it’s the programmer’s responsibility. And there really is only one kind of managed resource that we care about in .NET today — memory. The programmer tells the runtime to allocate memory and after that it’s up to the runtime to figure out when the memory can freed. The mechanism that .NET uses for this purpose is called garbage collection.

Implement IDispose interface and use Using statement.

 

 

Setting an object to null vs Dispose()

 

This is almost never required for the sake of garbage collection. When it’s a local variable, the JIT is usually smart enough (in release mode) to know when you’re not going to use a reference again.

 

When you dispose an object, the resources are freed. When you assign null to a variable, you’re just changing a reference.

myclass=null;

After you execute this, the object myclass was referring to still exists, and will continue to until the GC gets around to cleaning it up. If Dispose is explicitly called, or it’s in a using block, any resources will be freed as soon as possible.

 

 

try

{

myclass = new MyClass();

}

finally

{

myclass = null; // Doesn’t mean disposing / cleaning memory. The GC will do clean for you if there is no references to it anymore.

}

 

The one time where it may be worth setting a local variable to null is when you’re in a loop, and some branches of the loop need to use the variable but you know you’ve reached a point at which you don’t. For example:

 

SomeObject foo = new SomeObject(); for (int i=0; i < 100000; i++){    if (i == 5)    {        foo.DoSomething();        // We’re not going to need it again, but the JIT        // wouldn’t spot that        foo = null;    }}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s