Bil*_*ell 23 java garbage-collection jvm memory-leaks sun
我正在阅读Java平台性能(遗憾的是,因为我最初提出这个问题,链接似乎从互联网上消失了),A.3.3节让我很担心.
我一直在假设退出范围的变量不再被视为GC根,但本文似乎与此相矛盾.
最近的JVM,特别是Sun的1.6.0_07版本,仍然有这个限制吗?如果是这样,那么我有很多代码要分析......
我问这个问题是因为这篇论文是从1999年开始的 - 有时情况发生了变化,特别是在GC世界.
由于论文不再可用,我想解释一下这个问题.本文暗示,在方法退出之前,在方法内定义的变量将被视为GC根,而不是直到代码块结束.因此,必须将变量设置为null,以允许引用的Object被垃圾回收.
这意味着在main()方法中的条件块中定义的局部变量(或包含无限循环的类似方法)将导致一次性内存泄漏,除非在它退出范围之前将变量置为空.
所选答案的代码很好地说明了这个问题.在文档中引用的JVM版本中,当foo对象在try块结束时退出作用域时,不能对其进行垃圾回收.相反,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];
}
}
}
Run Code Online (Sandbox Code Playgroud)
在我的机器(jdk1.6.0_05)上打印:
从主要建构
从主要结束
所以看起来问题已得到解决.
请注意,使用System.gc()而不是循环不会导致由于某种原因收集对象.
| 归档时间: |
|
| 查看次数: |
1870 次 |
| 最近记录: |