退出代码块后适用于垃圾回收的变量

huangapple go评论78阅读模式
英文:

Variables eligible for GC after exit from block-code

问题

让我们假设我有这段代码:

public static void someMethod(){
    
    int sum = 0;
    {

        int a = 3;
        int b = 4;
        sum = a + b;

    }

    //a和b在这里不可见
    //但a和b是否会有资格进行垃圾回收?

    //更多代码

}

我的问题是,如果在退出代码块后,ab是否有资格进行垃圾回收,还是只有在someMethod完成后才会被回收?

英文:

Let's say I have this peace of code:

public static void someMethod(){
    
    int sum = 0;
    {

        int a = 3;
        int b = 4;
        sum = a + b;

    }

    //a and b is not visible here
    //but a and b will be eligible for GC?

    //more code

}

My question is if a and b are eligible for GC after execution exit from that block or only after the someMethod is done.

答案1

得分: 1

在理论上,任何局部变量一旦超出其作用域,就不再是垃圾收集根对象。(即使通过嵌套类等方式存在对变量的非局部访问。在这种情况下,变量中的值将被复制到另一个具有较长生命周期的(合成的)变量中。)

在实践中,JVM 实际上可能会等到封闭的方法调用返回。这取决于实现。

但在你的示例中:

  1. JIT 编译器可能会优化掉那些局部变量。
  2. 它们是原始变量,因此它们不会持有对象的引用。垃圾收集器不会注意它们。

一般情况下,你通常不需要担心这个问题。一些变量稍后变得不可达比严格必要的时间稍晚很少会有影响。

但考虑以下情况:

public static void longRunningMethod() {
    // 做一些事情
    {
       Map<X, Y> bigMap = ... // 创建并填充一个巨大的映射
       // 使用 bigMap
       bigMap = null;
    }
    // 长时间运算
}

如果你有明确的证据表明由于 bigMap 导致了“垃圾滞留”问题,你可能会考虑像上面那样将其赋值为 null。另一方面,该赋值也可能成为被优化掉的候选项!

英文:

In theory any local variable ceases to be a GC root as soon as it goes out of scope. (Even if there is non-local access to the variable via a nested class, etc. In that case, the value in the variable will have copied into another (synthetic) variable with a longer lifetime.)

In practice, the JVM may actually wait until the enclosing method call returns. It is implementation dependent.

But it your example:

  1. Those local variables could be optimized away by the JIT compiler.
  2. They are primitive variables, so they don't hold references to objects anyway. The GC won't pay any attention to them.

In general, you wouldn't normally worry about this. It rarely matters that a few variables become unreachable a bit later than is strictly necessary.

However consider the following:

public static void longRunningMethod() {
    // do stuff
    {
       Map&lt;X, Y&gt; bigMap = ... // create and populate a huge map
       // use bigMap
       bigMap = null;
    }
    // long running computation
}

If you had clear evidence of a "garbage retention" problem due to bigMap, you might consider assigning null to it, as above. On the other hand, that assignment could also be a candidate for being optimized away!

huangapple
  • 本文由 发表于 2020年10月7日 23:09:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/64246987.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定