有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

垃圾收集如果没有引用变量,java GC如何工作?

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

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

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

(new TestObject()).dosomething();

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


共 (1) 个答案

  1. # 1 楼答案

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

    编译以下程序

    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
    

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

    作为参考,here are the byte code instructions