This is not a memory leak, just sloppy coding on the part of the author(s) of AMProLibrary.
As you observed, the profiler is telling you that the referenced object is of type "Finalization Handle". What that means is that it is coming from the finalizer queue. The finalizer queue is what the .NET garbage collector uses to hold all objects that implement a finalizer method. The finalizer is the mechanism used to ensure that unmanaged resources are properly released during garbage collection. An object that contains unmanaged resources implements the IDisposable
pattern, including the Finalize
method, which is where the unmanaged resources are released. When the garbage collector processes "finalizable" objects (as indicated by the value of a bit in the object's header), it moves them into the finalizer queue. During collection, the GC iterates through the finalizer queue and calls the Finalize
method on each of those objects.
What the author of the library evidently failed to do is to call GC.SuppressFinalize()
from within the Dispose
method. This normally removes the object from the finalizer queue by clearing the "finalizable" bit in the object's header, and indicates that the Finalize
method does not need to be called.
For testing purposes, you can force the finalizers to run by calling the GC.WaitForPendingFinalizers
function. For example:
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.GC.Collect();
However, you should not actually use code like this in a production application. Forcing a collection rarely makes sense. This will just prove the validity of the hypothesis stated above.
In general, you should not rely on the finalizer to release unmanaged resources. All objects that implement IDisposable
should be explicitly disposed of by your code, either by manually calling the Dispose
method or, preferably, by wrapping their creation in a using
block that will automatically call Dispose
when the block's scope is exited.