Get Rid of Disposable and My Object in .NET – the memory lingers on

I have researched the tricky subject of Garbage collection some more. In short, read this article on the fundamentals and you will be wiser.

I think the problem with Garbage Collection is that it’s something that’s meant to just work. However, when you are running a program and the memory doesn’t do as you want it to, then you start to feel a lack of control and start doing some coding Voodoo to try to make things better. If you are not careful, you will make things worse.

Example

// and then free up the memory
GC.Collect();      

This seems to cure a problem – you get some memory back. However, it makes things worse, because it makes some short-lived objects go up a generation and last longer, increasing the overall baseline of memory usage. You should never need to call GC.Collect unless you’re doing something crazy.

The IDisposable pattern promises tidy up, but all it is there for is to clear up unmanaged resources. It doesn’t release CLR memory, it leaves that to the garbage collector. If an object uses the Dispose pattern and has a finalizer, then it will actually be longer-lived than if it does not. This is because any object with a finalizer needs to be scheduled to have that finalizer run, and so goes up a generation. Using Dispose on that object will cause its “SuppressFinalize” method to be called, and then the finalizer will not be needed and the lifetime comes back down to normal.

Put simply, IDisposable objects are longer lived unless you Dispose them… and if the reason you make them IDisposable was to control when they are collected, then you’re wasting your time as they still need the Garbage Collector and it’s still going to make you wait. So going round adding IDisposable and finalizers to things makes life worse unless you also go around disposing everything.

There’s the other bit of coding voodoo – set object reference to null.

var v = new Something();

// we don't need v anymore
v = null; // now it is gone

If the parent object – i.e. the one whose code we’re looking at above, is itself about to die, then the above doesn’t add any benefit. In short, setting a reference to null doesn’t make GC any better or worse. But…

var v = new MassiveObject(“1Gb”);
.
.
.
v = new MassiveObject(“1Gb”);

In the above, there is a period where both MassiveObject object MUST be in memory as the = on the last line is not evaluated until the new is finished during which time the MassiveObject from line 1 is still referenced.

So perhaps in the above situation (which never happens) you could do:

var v = new MassiveObject(“1Gb”)
v = null; // enable massive object to be collected
v = new MassiveObject(“1Gb”)

This might help if the GC was being particularly clever… but would you ever really need this? Probably not.

Overall, the best way to use garbage collection is to stop trying to control it and let it do its job.

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 )

Google+ photo

You are commenting using your Google+ 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 )

Connecting to %s