【问题标题】:GC roots and local variablesGC 根和局部变量
【发布时间】:2011-12-07 01:41:10
【问题描述】:

在查看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 可以更早地收集它?

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

【问题讨论】:

标签: c# garbage-collection gc-roots


【解决方案1】:

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

C# 是命令式语言,因此 GC 并未被设计为了解副作用。

【讨论】:

  • 你确定你在回答这个问题吗?
  • @Mehrdad:Tia 确实回答了;只是以比我更简短的方式。
  • @DanielMallott:我不明白为什么 object 保持活动状态与触发垃圾收集有关...评论说这会阻止 GC是“积极的”,而这个答案只是说该对象没有被收集。
  • @Mehrdad:GC 天生具有攻击性。它的诀窍是将对象保持在范围内 - 在这种情况下,通过在方法结束时调用它。否则,GC 将(可能)在它认为已将对象带出范围时立即收集它。原题中的具体案例,只是微软告诉你怎么玩GC的一个案例。
  • @DanielMallott:保持对象存活并不意味着 GC 的攻击性会降低——它只是意味着它在运行时不会收集对象。
【解决方案2】:

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

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

【讨论】:

  • 即使运行了 100 次 GC 循环,只要方法没有返回,对象仍然在作用域内,所以不是这样。似乎允许 GC 进行活性分析并忽略其根集的“死”变量(也许 GC 确实对 JIT 代码而不是字节码表示起作用,在这种情况下,这是通常优化的一个简单副作用- 可以很好地解释以这种方式指定它)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多