문제

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 ;) )

도움이 되었습니까?

해결책

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.

다른 팁

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top