GC.Collect does not call IronPython destructor

467 Views Asked by At

I have a simple IronPython class which implements a destructor (__del__) and write some thing to the console in it. If there is not reference to the instance any more and i call GC.Collect for testing purpose, the destructor will never be called. Is this correct? Does the DLR/IP has it's own memory management on top of the clr/gc?

1

There are 1 best solutions below

1
Dan Puzey On

This is perhaps a broader question than you realize.

The typical behaviour of a class with a finalizer is that the GC will move the item into a finalizer queue on collect. The queue of objects is processed separately (though you can call GC.WaitForPendingFinalizers() to block until it completes). This means that the object is still rooted (there is a reference to it from the finalizer queue, even if not from your code!) and so will typically survive GC and be promoted to the next generation.

For this reason you might have to GC twice before your item is cleaned up. It also means that the finalizer will by definition occur at some arbitrary time after your collect. If you call GC.WaitForPendingFinalizers(), though, you should see your finalizer called.

To avoid all this undesireable behaviour, it is typical to implement the IDisposable interface to explicitly handle cleanup of unmanaged resources. If you look at a typical example implementation from documentation, you will see that the Dispose method typically calls GC.SuppressFinalize(this). This means that, if you dispose of the object cleanly in your code, the finalizer need not be called at all.