My point is that if the local variables of a method aren't considered as root
references, what prevents the GC from collection local objects prematurely?
Meaning, how does the GC knows (if at all) when do I stop using an object
inside a method's body?
> Hi Amir!
>
[quoted text clipped - 40 lines]
>
> GP
Ben Voigt - 29 May 2007 18:50 GMT
> My point is that if the local variables of a method aren't considered as
> root
> references, what prevents the GC from collection local objects
> prematurely?
> Meaning, how does the GC knows (if at all) when do I stop using an object
> inside a method's body?
Because reflection against local variables is not possible, they really are
scoped to the enclosing function. Therefore, the compiler can analyze which
locals are used by which instructions, and determine the usable lifetime of
those variables precisely.
I've seen several demos where the GC collects a object referenced by a local
variable that is in scope but dead (not mentioned again).
>> Hi Amir!
>>
[quoted text clipped - 44 lines]
>>
>> GP
Jon Skeet [C# MVP] - 29 May 2007 21:05 GMT
> My point is that if the local variables of a method aren't considered as root
> references, what prevents the GC from collection local objects prematurely?
They *are* considered root references, but only to the point of the
last possible read.
> Meaning, how does the GC knows (if at all) when do I stop using an object
> inside a method's body?
Because it can analyse the IL and spot that there's no code in the rest
of the method that will read the variable's value.

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Günter Prossliner - 30 May 2007 10:13 GMT
Hi Amir!
> My point is that if the local variables of a method aren't considered
> as root references, what prevents the GC from collection local
> objects prematurely? Meaning, how does the GC knows (if at all) when
> do I stop using an object inside a method's body?
Stack - References are only considered as Roots when they are accessed after
the current Execution-Pointer (as Jon pointed out, only read-access in
encountered).
Allthough AFIAK there is nothing about this in the official docs (specs),
but there are articles where this behavior was been described:
http://msdn.microsoft.com/msdnmag/issues/1100/GCI/default.aspx
"In addition, any local variable/parameter object pointers on a thread's
stack are considered part of the application's roots. Finally, any CPU
registers containing pointers to objects in the managed heap are also
considered part of the application's roots. The list of active roots is
maintained by the just-in-time (JIT) compiler and common language runtime,
and is made accessible to the garbage collector's algorithm"
The GC gets this information from the JIT-Compiler, there is no need to
inject code.
GP
<snip>
> Worst Example:
> try{
[quoted text clipped - 8 lines]
> In this case you won't help the CLR in any way. Without "x = null" the CLR
> could collect the Foo - Instance very earlier.
<snip>
No - the CLR detects that the assignment doesn't count as "reading" the
variable, so it can still collect the instance before the x=null; line
would be executed.

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Amir Shitrit - 30 May 2007 08:42 GMT
But how exactly does the CLR know when it's safe to collect it?
Does it inject some code to do so?
> <snip>
>
[quoted text clipped - 16 lines]
> variable, so it can still collect the instance before the x=null; line
> would be executed.
Ben Voigt [C++ MVP] - 30 May 2007 14:35 GMT
> But how exactly does the CLR know when it's safe to collect it?
> Does it inject some code to do so?
The JIT generates some mapping from instruction pointer to information on
stack-local roots. The GC suspends all other threads, and then walks the
call stack of each, inspecting the stack-local roots that the JIT indicated
were being used at the current location (in addition to global roots,
basically the list of System.Type objects maintained by the runtime, which
reach each constructed Type, which reach the static members, and so on).
Naturally not all local variables are roots, an int for example is the right
size on 32-bit, but doesn't represent the address of a managed object
instance, so the GC needn't consider it.
>> <snip>
>>
[quoted text clipped - 17 lines]
>> variable, so it can still collect the instance before the x=null; line
>> would be executed.
Göran Andersson - 07 Jul 2007 01:26 GMT
> But how exactly does the CLR know when it's safe to collect it?
> Does it inject some code to do so?
The code is analyzed at compilation, so the CLR knows the "usage span"
of each variable.
There is no code injected for garbage collection. There is absolutely
nothing extra that is happening when a variable goes out ot scope or
"usage span". Only the garbage collector knows about things like this,
the rest of the code has no clue.

Signature
Göran Andersson
_____
http://www.guffa.com