4

在查看Timer 文档时,我遇到了以下带有此注释的示例:

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

这是否意味着允许 C# 中的 GC 垃圾收集局部变量,即使它会产生副作用?大概是因为之后我不再访问计时器,GC 可以更早地收集它?

如果我正确理解这一点,我不确定我是否喜欢这种优化(但我可能不会;))

4

2 回答 2

2

是的,GC 可能会在范围结束之前收集局部变量,在最后一次使用变量之后。将 GC.KeepAlive 放在方法的末尾可确保变量在调用 KeepAlive 之前一直处于“活动状态”。

C# 是命令式语言,因此 GC 并未被设计为了解任何有关副作用的信息。

于 2011-12-07T01:56:56.183 回答
1

据我了解 GC,它会将任何它认为不再需要的变量或对象标记为在下一个 GC 循环期间作为垃圾收集的候选者。我不确定我是否理解这里的特定应用程序,但我确实知道在某些情况下,GC 可能会在仍需要资源时将其标记为收集(但由于代码的编写方式而不会出现)。

通常,在方法期间,对象或变量在方法调用期间保持在范围内,但如果方法调用持续时间长于 GC 周期之间的时间,则 GC 可能会将您的 Timer 对象视为超出范围并将其标记为收集. 添加 GC.KeepAlive 方法会强制 GC 等到方法退出后再对 Timer 对象进行操作。

于 2011-12-07T01:53:45.320 回答