gpt4 book ai didi

java - 在最近的 JVM 中,不可见的引用仍然是一个问题吗?

转载 作者:IT老高 更新时间:2023-10-28 20:35:49 24 4
gpt4 key购买 nike

我正在阅读 Java Platform Performance (遗憾的是,自从我最初提出这个问题以来,该链接似乎已经从互联网上消失了),A.3.3 节让我担心。

我一直在假设退出范围的变量将不再被视为 GC 根,但这篇论文似乎与此相矛盾。

最近的 JVM,尤其是 Sun 的 1.6.0_07 版本,是否还有这个限制?如果是这样,那我还有很多代码要分析……

我问这个问题是因为这篇论文是 1999 年的 - 有时情况会发生变化,尤其是在 GC 领域。


由于该论文不再可用,我想解释一下这个问题。该论文暗示在方法内定义的变量将被视为 GC 根,直到方法退出,而不是直到代码块结束。因此,必须将变量设置为 null 以允许对引用的对象进行垃圾回收。

这意味着在 main() 方法(或包含无限循环的类似方法)的条件 block 中定义的局部变量会导致一次性内存泄漏,除非您在变量退出范围之前将其置空.

来自 chosen answer 的代码很好地说明了这个问题。在文档中引用的 JVM 版本上,当 foo 对象在 try block 结束时超出范围时,无法进行垃圾回收。相反,JVM 将保持打开引用直到 main() 方法结束,即使任何东西都不可能使用该引用。

这似乎是一个想法的起源,即使变量引用为空将有助于垃圾收集器,即使该变量即将退出范围。

最佳答案

这段代码应该可以清除它:

public class TestInvisibleObject{
public static class PrintWhenFinalized{
private String s;
public PrintWhenFinalized(String s){
System.out.println("Constructing from "+s);
this.s = s;
}
protected void finalize() throws Throwable {
System.out.println("Finalizing from "+s);
}
}
public static void main(String[] args) {
try {
PrintWhenFinalized foo = new PrintWhenFinalized("main");
} catch (Exception e) {
// whatever
}
while (true) {
// Provoke garbage-collection by allocating lots of memory
byte[] o = new byte[1024];
}
}
}

在我的机器 (jdk1.6.0_05) 上打印:

Constructing from main

Finalizing from main

看来问题已经解决了。

请注意,使用 System.gc() 代替循环不会因为某种原因导致对象被收集。

关于java - 在最近的 JVM 中,不可见的引用仍然是一个问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/271613/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com