繁体   English   中英

如果没有引用变量,java GC如何工作?

[英]How does java GC work if there is no reference variable?

我知道如果指向对象的引用变量被手动设置为null或设置为指向另一个对象,则java GC可以销毁堆上的对象:

TestObject test = new TestObject();
test.dosomething();
test = null;

我的问题是,如果我在创建它时没有给该对象一个名称(引用变量),那么在完成对象后,如何释放该对象占用的内存:

(new TestObject()).dosomething();

在程序结束之前,这个对象会永远存在于堆上吗?

使用new创建对象并在其上调用dosomething()方法后,没有任何引用,因此它有资格进行垃圾回收。

即使您创建了两个使用引用指向彼此的对象,并且它们不再具有与根引用的连接,它们也将符合gc的条件(jvm可以在没有根连接的情况下检测此循环引用)。

因此,要回答你的问题: 没有在你的第二个例子对象将是GC-ED之后您调用dosomething就可以了。

只是一个注意事项:在实践中你不需要null引用(我实际上几乎从不这样做)它就足够了,如果你将它们保存在本地范围内,那么当你离开它时,局部变量就会被清理掉。

我将通过字节代码解释这个。 首先要注意的是,虽然对象存在可访问的引用,但无法收集该对象。 这方面的一个重要方面是,如果参考值在方法的堆栈帧中的堆栈上,则可以访问被引用的对象。 因此它不能被垃圾收集。

编译以下程序

public class Example {
    public static void main(String[]args) {
        new Example().sayHello();
    }

    public void sayHello() {}
}

运行javap -c Example会给你类似的东西

  public static void main(java.lang.String[]);
    Code:
      stack=2, locals=1, args_size=1
         0: new           #2                  // class Example
         3: dup
         4: invokespecial #3                  // Method "<init>":()V
         7: invokevirtual #4                  // Method sayHello:()V
        10: return

索引0new字节代码指令)创建一个新对象,并将对该对象的引用推送到堆栈上。 dup指令复制该值并将其推送到堆栈顶部。 所以你现在有两个对该对象的引用。 invokespecial使用一个, invokevirtual使用其他(他们弹出他们使用的参考值)。 一旦完成,就不再有对象的引用,它可以被垃圾收集。

作为参考, 这里是字节代码指令

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM