Releasing GCHandles on application exit
say I have
var hGCFile = GCHandle.Alloc(buffer, GCHandleType.Pinned)
And I P/Invoke some unmanaged function with
SaveStream(hGCFile.AddrOfPinnedObject())
Further, suppose the above function saves the buffer address and uses it throughout my application's lifetime.
In such a case, is there a benefit to calling
hGCFile.Free()
Before shutting down my application? It's just that I'd guess the CLR would do it anyw开发者_JAVA百科ay upon appdomain teardown
Well, the finalizer for buffer will never run. Hard to see how that could matter, you wouldn't be able to pin it if it was an object with anything interesting inside.
It is very unfriendly to the garbage collector, it has to constantly work around the obstacle and can't compact the heap well enough to give your app the best use of the CPU cache. Especially bad if it is in gen #0, it will be.
There is very rarely a good reason to give the GC such a hard time, just allocate real unmovable memory. Use Marshal.AllocCoTaskMem() and Marshal.StructureToPtr() (if and where needed). Now you do care about releasing that memory when unloading the AppDomain doesn't also terminate the process. That IntPtr will be gonzo.
But do note that the lifetime of the AppDomain is not in any way associated with the lifetime of unmanaged code. That DLL you loaded will not be unloaded along with the AppDomain. It isn't clear from your question whether this unmanaged code could still use that buffer, it could since it is still there. If it does, it is really important that you don't use pinned memory.
When the AppDomain
is unloaded, it's guaranteed that all memory allocated by the AppDomain
is released.
Read a few days ago that they actually got the memory consumption down to 12 bytes between before the AppDomain
was created and after it was unloaded :).
Once your application exits, you need to make sure all unmanaged resources are released. GCHandle
deals with the managed resource (CLR heap) so no action is required.
Not releasing a pinned GCHandle
will cause the GC not being able to move the objects and compress the used memory in heap. So this will be all managed memory and if app is exiting, it does not matter anymore.
精彩评论