GC Roots and Local Variables

While looking at the timer documentation, I looked at the following example with this comment:

// Normally, the timer is declared at the class level, // so that it stays in scope as long as it is needed. // If the timer is declared in a long-running method, // KeepAlive must be used to prevent the JIT compiler // from allowing aggressive garbage collection to occur // before the method ends. You can experiment with this // by commenting out the class-level declaration and // uncommenting the declaration below; then uncomment // the GC.KeepAlive(aTimer) at the end of the method. //System.Timers.Timer aTimer; code in between // If the timer is declared in a long-running method, use // KeepAlive to prevent garbage collection from occurring // before the method ends. //GC.KeepAlive(aTimer); 

Does this mean that GC in C # allows garbage to collect local variables, even if it has side effects? Presumably, because I am not getting access to the timer again, can the GC assemble it earlier?

Not sure if I’m a fan of such optimization, if I understand it correctly (but then I’m probably not so;))

+4
source share
2 answers

Yes, GC can collect a local variable before the end of the scope, as soon as after the last use of this variable. Putting GC.KeepAlive at the end of the method ensures that the variable is "alive" until KeepAlive is called.

C # is a required language, so GC was not designed to know anything about side effects.

+2
source

As far as I understand the GC, it will mark any variable or object that, in its opinion, is no longer needed as a candidate for garbage collection during the next GC cycle. I'm not sure that I understand the specific application here, but I know that there are times when the GC can mark a resource for a collection when it is still needed (but it doesn’t appear because of the way the code is written).

Typically, during methods, an object or variable remains in scope for the entire method call, but if the method call lasts longer than the time between GC loops, the GC can see your Timer object outside the scope and mark it for collection. Adding the GC.KeepAlive method causes the GC to wait until the method exits before acting on the Timer object.

+1
source

Source: https://habr.com/ru/post/1385032/


All Articles