1

According to this answer by a reasonably reliable source, in C#, an object can be collected as soon as the GC can prove it will no longer be used, even if references to it still exist. This can cause surprising early finalization issues.

If you specifically want to delay collection of an object until a certain point, what would be the best way to do so? We can't do it by simply keeping a reference to the object, and if we try to make some simple use of the reference to stop the GC, such operations would likely be optimized away. What can we do?

(The motivation for this question is an older question in Java where someone wanted to ensure that the referents of a list of WeakReferences wouldn't be collected while the WeakReferences were being sorted by their referents. As such, an explanation of how Java's behavior is similar or different to C#'s in this case and a solution for the corresponding problem in Java would also be appreciated.)

Community
  • 1
  • 1
user2357112
  • 260,549
  • 28
  • 431
  • 505

1 Answers1

1

You could consider GCHandle.Alloc to prevent managed objects from being collected:

http://msdn.microsoft.com/en-us/library/a95009h1%28v=vs.110%29.aspx

Do not forget to call Free when the GCHandle is no longer needed.

object obj = ....;
GCHandle handle = GCHandle.Alloc(obj);
// ....
// object o is protected from garbage collection 
// ....
handle.Free();

Note that (http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle.free%28v=vs.110%29.aspx)

The caller must ensure that for a given handle, Free is called only once.

AlexD
  • 32,156
  • 3
  • 71
  • 65
  • This looks a lot like what I'm looking for, but I'm not sure whether the restriction that the object must have only blittable members is a problem. – user2357112 Feb 14 '14 at 00:24
  • Hm... I would think the restriction is for `Pinned` handles, see http://msdn.microsoft.com/en-us/library/83y4ak54%28v=vs.110%29.aspx. But to create a `Pinned` handle, another overload is used: `GCHandle.Alloc(object, GCHandleType)`. Simple `GCHandle.Alloc(object)` uses `GCHandleType == Normal`. – AlexD Feb 14 '14 at 00:50