Disposed Instances
Usually, the number of disposed instances for any type should be zero or close to zero. If it is not zero, it may indicate a memory leak. However, there are several possible causes for disposed instances to exist:
There are still short-lived references to the instance, e.g. it may still be referenced by a local variable or an argument. In this case, when collecting another snapshot, the instance should have been garbage collected.
The instance is part of a pool. Disposing the instance simply returns it to the pool to allow it to be reused. In this case it is normal for the instance not to be garbage collected, and it is no indication of a memory leak.
Something else references the instance. This is a very likely memory leak, since usually the instance should no longer be used after it has been disposed. Use the root paths under instance details to try to find out why the instance has not been garbage collected.
An instance is usually considered to be disposed as soon as the Dispose()
method is called, but it is possible for a disposable class to hide the Dispose method and perform the disposal of the instance using a method with a more suitable name instead. For instance, several classes prefer the name Close()
. According to the Dispose pattern guideline, the method replacing Dispose should just call Dispose. Unfortunately, there is a possibility that the hidden Dispose method calls the replacing method. For instance:`
public class ResourceWrapper : IDisposable
{
public virtual void Close()
{
// Release native resources.
//
GC.SuppressFinalize( this );
}
void IDisposable.Dispose()
{
Close();
}
}
In this case, there is a risk that the disposal of the instance is missed and that the instance will be considered “undisposed” when collected.
An instance is considered to be disposed if:
The
Dispose()
method,orIDisposable.Dispose()
if the method is hidden, of the instance is called, before any call toFinalize()
.The
Dispose(bool)
method of the instance is called (if it exists), withtrue
as argument, before any call toFinalize()
.