Can I get GCHandles for a pinned object from an object?

I bind the object to .NET and get a GCHandle. I want to skip most of these GCHandle and forget about them (so that objects continue to pin). Later, for several objects I want to unlock them. At this point, I only have the object (or the address of the object).

It seems that every call to GCHandle pinning returns a new GCHandle. GCHandle.ToIntPtr and GCHandle.FromIntPtr show that native ints are equivalent to these GCHandles.

Can I get a GCHandle from an object or from an AddrOpPinnedObject?

+4
source share
2 answers

No, once you lose GCHandle, you will lose it forever. There is no concept of “handle to handle” in the garbage collector. You can create a new GCHandle object for the object, it will add an additional link. The object to which the descriptor references have been lost will be constantly referenced, this is a leak. Note that GCHandle is a type of structure.

The idea of ​​saving objects that are pinned for any period of time is detrimental to your perf program. In short, than giving the GC a more difficult time to work with obstacles, it also prevents it from properly compacting the pile. This increases the likelihood of cache misses, which are very expensive on modern cores. These side effects can last a while.

If you need pinned memory, allocate it using Marshal.AllocCoTaskMem (). It also prevents you from creating pointers to managed data that have an unpredictable memory structure. A layout that differs between different versions of the JIT compiler and is highly dependent on the declaration of a structure or class. Only Marshal.StructureToPtr () can give you a solid guarantee.

+3
source

For those you need to free, save the GCHandles and use Free . GCHandle knows about the object, not the other way around.

It's also nice that you want to save Pinned objects. I hope you understand that you will interfere with the normal functioning of the GC.

0
source

All Articles