GC roots and local variables

倖福魔咒の 提交于 2019-12-10 17:39:24

问题


While looking at the Timer documentation I ran across 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 the GC in C# is allowed to garbage collect local variables even if it would have side effects? Presumably because I'm not accessing the timer afterwards again the GC can collect it earlier?

Not sure I'm a fan of such an optimization if I understand this correctly (but then I probably don't ;) )


回答1:


Yes, GC might collect local variable before ending of the scope, as soon as after last use of the variable. Putting GC.KeepAlive at the end of the method ensures that the variable will be 'alive' until the KeepAlive call.

C# is imperative language so the GC hasn't been designed to know anything about side effects.




回答2:


As far as I understand the GC, it will mark any variable or object that it believes is no longer needed as a candidate for Garbage Collection during the next GC cycle. I'm not certain I understand the particular application here, but I do know there are cases where the GC might mark a resource for collection when it is still needed (but does not appear so due to the way the code is written).

Normally, during methods, an object or variable stays in scope for the duration of the method call, but if the method call lasts longer than the time between GC cycles, the GC might see your Timer object as out of scope and mark it for collection. Adding the GC.KeepAlive method forces the GC to wait until the method exits before acting on the Timer object.



来源:https://stackoverflow.com/questions/8409398/gc-roots-and-local-variables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!