Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Struct with reference types and GC?

I was wondering ,

An Instance of class is on the Heap. ( value types inside it are also in the heap).

But what about the opposite case ?

There is one question here but it didn't mention any GC related info.

So - How does GC handle this situation ?

public struct Point 
{
object o ;

   public int x, y;

   public Point(int p1, int p2) 
   {
   o = new Object();
      x = p1;
      y = p2;    
   }
}
like image 445
Royi Namir Avatar asked Jul 25 '12 11:07

Royi Namir


2 Answers

Point includes a reference to an object on the heap. This will become eligible for collection as soon as no more copies of that Point exist with that reference. Noting that:

Point p1 = new Point(1,2);
Point p2 = p1;

is 2 copies, each with a reference to the same object on the heap. If those points are stored as fields on an object somewhere, then obviously the lifetime of the object will be at least as long as the object with those fields. If those points are only variables on the stack, then it gets more complex, because the GC may take into account whether a variable is ever read again. If it isn't, the variable might not effectively exist (or: it might).

The path can be very indirect, but it essentially comes down to: can GC get to the object, starting from the GC roots.

like image 190
Marc Gravell Avatar answered Oct 12 '22 13:10

Marc Gravell


The GC does search for object roots in

  • GC Handles (static variables are roots which are GC Handles as well)
  • All Thread Stacks
  • CPU Registers

In your case is the struct normally located inside a the thread stack and therefore searched. If it is boxed then it resides on the managed heap as a pseudo object. But you can be assured that this thing is correctly counted by the GC. Since it does contain an object it is not a blittable type anymore and cannot be passed to unmanaged code via PInvoke.

There is an issue with PInvokes if you pass a struct to it that it will be GCed even if the unmaanged call is still in progress which does get you only in release builds because for debug builds the lifetime of variables is extended until the method is left. In release mode the GC collects much more aggressively.

Edit1: Structs as members in a class objects are no special case. The GC wil inspect all class fields for class references in embedded structs as well.

like image 36
Alois Kraus Avatar answered Oct 12 '22 15:10

Alois Kraus