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 anyway 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.