在查看Timer documentation时,我使用以下评论运行了以下示例:
// 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可以提前收集它?
如果我理解正确的话,我不确定我是这种优化的粉丝(但我可能不会这样做;)
答案 0 :(得分:2)
是的,在最后一次使用变量之后,GC可能会在结束范围之前收集局部变量。将GC.KeepAlive放在方法的末尾可确保变量在KeepAlive调用之前处于“活动状态”。
C#是命令式语言,所以GC的设计并不是为了解副作用。
答案 1 :(得分:1)
据我了解GC,它会在下一个GC周期中标记它认为不再需要作为垃圾收集候选者的任何变量或对象。我不确定我是否理解这里的特定应用程序,但我知道有些情况下GC可能会在需要时标记要收集的资源(但由于编写代码的方式不会出现这种情况)。 / p>
通常,在方法期间,对象或变量在方法调用期间保持在范围内,但如果方法调用持续的时间长于GC循环之间的时间,则GC可能会将您的Timer对象视为超出范围并标记它收集。添加GC.KeepAlive方法会强制GC等待方法退出,然后再对Timer对象执行操作。