Java - 是否可以对正在执行方法的对象进行垃圾回收?

在Java中,我做了如下事情,而没有多想:

public class Main {

    public void run() {
        // ...
    }

    public static void main(String[] args) {
        new Main().run();
    }
}

但是,最近我不确定这样做是否安全。毕竟,创建对象后没有对对象的引用(好吧,有引用,但这算数吗?),所以看起来垃圾回收器可能会在执行某些内容时删除对象。因此,也许该方法应如下所示:Mainthismain

    public static void main(String[] args) {
        Main m = new Main();
        m.run();
    }

现在,我很确定第一个版本是有效的,我从来没有遇到过任何问题,但我想知道它是否在所有情况下都是安全的(不仅在特定的JVM中,而且最好根据语言规范对这种情况的看法)。


答案 1

如果正在执行对象方法,则表示有人拥有该引用。所以不,在执行方法时,对象不能被GC化。


答案 2

在大多数情况下,垃圾回收是透明的。它的存在是为了消除手动内存管理的不必要的复杂性。因此,它似乎不会被收集,但实际发生的事情更微妙。

简单来说,编译器可以完全省略对象的构造。(通过编译器,我的意思是比javac更低级别的编译器。字节码将是源的文字音译。更晦涩难懂的是,垃圾回收通常在单独的线程中运行,并且实际上删除了未访问的对象,因为正在运行该对象的方法。

如何观察呢?决赛中的常见嫌疑人。它可以与在对象上运行的方法同时运行。通常,您会在 finaliser 和 normal 方法中使用块来解决此问题,这会引入必要的发生前关系。synchronized