java - 未使用的对象在堆栈中仍然可见时是否可用于垃圾回收?

标签 java garbage-collection jvm

在下面的例子中有两个功能相同的方法:

public class Question {

    public static String method1() {
        String s = new String("s1");
        // some operations on s1
        s = new String("s2");
        return s;
    }

    public static String method2() {
        final String s1 = new String("s1");
        // some operations on s1
        final String s2 = new String("s2");
        return s2;
    }
}

然而,在第一个(method1)中,字符串“s1”在return 语句之前显然可用于垃圾回收。在第二个(method2)中,字符串“s1”仍然可以访问(尽管从代码审查的角度来看它不再被使用)。

我的问题是 - jvm 规范中是否有任何内容表明一旦变量在堆栈中未被使用,它就可以用于垃圾回收?

编辑: 有时变量可以引用像完全渲染的图像这样的对象并且对内存有影响。

我问是出于实际考虑。我在一个方法中有大量内存贪婪代码,我想我是否可以通过将这个方法分成几个小方法来帮助 JVM(一点点)。

我真的更喜欢没有重新分配的代码,因为它更容易阅读和推理。

更新:根据 jls-12.6.1 :

Java compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner

所以看起来 GC 可能会声明仍然可见的对象。然而,我怀疑这种优化是在离线编译期间完成的(它会搞砸调试)并且很可能是由 JIT 完成的。

最佳答案

不,因为您的代码可以想象地检索它并用它做一些事情,并且抽象的 JVM 不会考虑前面的代码。然而,一个非常、非常、非常聪明的优化 JVM 可能会分析前面的代码并发现永远无法引用 s1,并对其进行垃圾回收。不过,您绝对不能指望这一点。

关于java - 未使用的对象在堆栈中仍然可见时是否可用于垃圾回收?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19896866/

相关文章:

java - 字节码以未记录的方式随时间变化

java - 从 linux 中的 jvm 中查找硬和软打开文件限制(ulimit -n 和 ulimit -Hn)

java - Exoplayer 音频未在后台服务中播放

javascript - 我的 HTML5 游戏时不时会卡顿,如何判断是不是垃圾回收引起的?

java - Spring 配置 XML 架构 : with or without version?

java - Java 有析构函数吗?

java - 在 scala 中加载 mongodb 集合时超出 GC 开销限制

java - 流程卡在流程构建器上

java - 获取端点的指标

java - 配置类 : ClassNotFoundException 的应用程序监听器时出错