在最近的JVM中,不可见引用仍然是一个问题? [英] Are invisible references still an issue in recent JVMs?

查看:88
本文介绍了在最近的JVM中,不可见引用仍然是一个问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读 Java平台性能 (遗憾的是,自从我提出这个问题以来,这个链接似乎从互联网上消失了),A.3.3节让我担心。

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



最近的JVM,特别是Sun的1.6.0_07版本,仍然有这个限制?如果是这样,那么我有很多代码可以分析......



我问这个问题是因为这篇论文是从1999年开始的 - 有时候情况会改变,特别是在世界上GC。






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



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



选择的答案很好地说明了这个问题。在文档中引用的JVM版本中,当foo对象在try块末尾处于范围之外时,它不能被垃圾回收。相反,JVM将保持打开引用,直到main()方法结束,即使不可能使用该引用。



这似乎是即使变量即将退出作用域,变量引用无效也会有助于垃圾收集器。

解决方案

这个代码应该清除它:

  public class TestInvisibleObject {
public static class PrintWhenFinalized {
private String s;
public PrintWhenFinalized(String s){
System.out.println(构造自+ 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){
//通过分配大量内存来唤起垃圾回收
字节[] o =新字节[1024];





在我的机器上(jdk1。
$ b


从main构造

从main

所以看起来问题已经解决。



请注意,使用由于某种原因,System.gc()而不是循环不会导致收集对象。


I was reading Java Platform Performance (sadly the link seems to have disappeared from the internet since I originally posed this question) and section A.3.3 worried me.

I had been working on the assumption that a variable that dropped out of scope would no longer be considered a GC root, but this paper appears to contradict that.

Do recent JVMs, in particular Sun's 1.6.0_07 version, still have this limitation? If so, then I have a lot of code to analyse...

I ask the question because the paper is from 1999 - sometimes things change, particularly in the world of GC.


As the paper is no longer available, I'd like to paraphrase the concern. The paper implied that variables that were defined inside a method would be considered a GC root until the method exited, and not until the code block ended. Therefore setting the variable to null was necessary to permit the Object referenced to be garbage collected.

This meant that a local variable defined in a conditional block in the main() method (or similar method that contained an infinite loop) would cause a one-off memory leak unless you nulled a variable just before it dropped out of scope.

The code from the chosen answer illustrates the issue well. On the version of the JVM referenced in the document, the foo object can not be garbage collected when it drops out of scope at the end of the try block. Instead, the JVM will hold open the reference until the end of the main() method, even though it is impossible for anything to use that reference.

This appears to be the origin of the idea that nulling a variable reference would help the garbage collector out, even if the variable was just about to drop out of scope.

解决方案

This code should clear it up:

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];
    } 
  }
}

On my machine (jdk1.6.0_05) it prints:

Constructing from main

Finalizing from main

So it looks like the problems has been fixed.

Note that using System.gc() instead of the loop does not cause the object to be collected for some reason.

这篇关于在最近的JVM中,不可见引用仍然是一个问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆