Reputation: 53
I pin an object on .NET and get a GCHandle. I want to leak most of these GCHandle and forget about them (so the objects continue to be pinned). Later, for a few objects I want to unpin them. At that point I only have the object (or the address of the object).
It seems each GCHandle pinning call returns a fresh GCHandle. The GCHandle.ToIntPtr and GCHandle.FromIntPtr show the native ints are equivalent to these GCHandles.
Is it possible to get the GCHandle(s) from an object or from the AddrOfPinnedObject?
Upvotes: 5
Views: 1548
Reputation: 942020
No, once you lose a GCHandle then you've lost it forever. There is no notion of a 'handle to a handle' in the garbage collector. You can only create a new GCHandle for an object, it will add an extra reference. The object this lost handle references will be permanently referenced, it is a leak. Note that GCHandle is a struct type.
The idea of keeping objects pinned for any length of time is detrimental to your program's perf. Short from giving the GC a harder time to work around the obstacles, it also prevents it from compacting the heap properly. This increases the likelihood of cache misses, very expensive on modern cores. These side effects can last for a while.
If you need pinned memory then allocate it with Marshal.AllocCoTaskMem(). This also stops you from creating pointers to managed data that has an unpredictable memory layout. Layout that differs between different versions of the JIT compiler and is highly dependent on the struct or class declaration. Only Marshal.StructureToPtr() can give you hard guarantees.
Upvotes: 4
Reputation: 81680
For those ones you need to free, keep GCHandles and use Free
. GCHandle knows about the object and not the other way around.
Also it is not great that you want to keep the objects Pinned. I hope you realise you will be preventing GC to work correctly.
Upvotes: 0