假設定義了一個局部變量,然后傳遞給 Thread 構(gòu)造函數(shù),在那里它被保存為該線程的私有字段。然后,線程開始連續(xù)運行(基本上是永遠),而原始方法結(jié)束。局部變量引用沒了,但是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(...) } }}
1 回答

慕尼黑的夜晚無繁華
TA貢獻1864條經(jīng)驗 獲得超6個贊
簡而言之,是的,GC確實考慮了存儲在MyThread
類中的引用,并且不會刪除引用的對象。這是因為 Java 的垃圾收集器只會銷毀無法訪問的對象,即代碼中任何地方都沒有引用的對象(不完全是一般規(guī)則,請查看弱引用)。
該變量foo
不是一個實際的對象,而是對一個對象的引用。當您傳遞foo
到MyThread
的構(gòu)造函數(shù)時,您不是在傳遞對象,而是對它的引用。在構(gòu)造函數(shù)內(nèi)部,您正在復制此引用并將其存儲在MyThread
. 由于run()
該類的方法將“永遠”運行(意味著 的實例MyThread
“活著”),有問題的引用將“永遠”活著,從而防止被引用的對象被垃圾收集。
請注意,MyThread
's name 是錯誤的,可以這么說。它不會擴展Thread
,因此,它不是一個線程。它只是Runnable
接口的一個實現(xiàn)。更準確的名稱是MyRunnable
.
添加回答
舉報
0/150
提交
取消