java GC是否考虑了另一个线程中的引用?

Ray*_*eng 0 java garbage-collection nullpointerexception

假设定义了一个局部变量,然后传递给一个Thread构造函数,在那里它被保存为该线程的私有字段.然后,线程开始连续运行(永远,基本上),而原始方法结束.

局部变量引用已经消失,但GC是否考虑了Thread对象存储的引用?

我的方案类似于此示例代码段:

...

public static void Main(String... args) {
  Foo foo = new Foo()
  MyThread thread = new MyThread(foo)
  ExecutorService executor = Executors.newSingleThreadExecutor();
  executor.execute(thread)
}

...

public class MyThread implements Runnable {

  private Foo foo;

  public MyThread(Foo foo) {
     this.foo = foo;
  }

  public void run() {
     while (true) {
         this.foo.print(); // << throws NullPointerException
         sleep(...)
     }
  }
}
Run Code Online (Sandbox Code Playgroud)

Tal*_*dar 5

简而言之,是的,GC确实考虑了存储在MyThread类中的引用,并且不会删除引用的对象.这是因为Java的垃圾收集器只会破坏无法访问的对象,即代码中未被引用的对象(不完全是一般规则,请查看弱引用).

变量foo不是实际对象,而是对一个对象的引用.当你传递fooMyThread构造函数时,你没有传递对象,而是传递它.在构造函数中,您将复制此引用并将其存储在成员变量of中MyThread.由于run()该类的方法将"永久"运行(意味着一个实例MyThread是"活着的"),因此所涉及的引用将"永远"存在,从而防止引用的对象被垃圾收集.

注意,MyThread这个名字是错的,可以这么说.它没有扩展Thread,因此,它不是一个线程.它只是Runnable界面的一个实现.一个更准确的名字就是MyRunnable.