我寫了一些代碼,我可能需要創建一個無限數量的未來對象(java.util.concurrent.Future)。Java併發:是否取消他們需要收集垃圾的期貨?
但是我擔心在某個時候內存不足。
問題的夫婦在這裏:
- 是否JVM知道,一旦未來已經完成,它沒有被任何地方refernced,因此可享有GC(即使在其中創建它的線程仍然活着和跑步)?
- 理想情況下,我不想跟蹤這些期貨本身。但是,如果我確實保留這些期貨的參考資料並定期對它們進行取消,那麼它們是否可以用於GC?
我寫了一些代碼,我可能需要創建一個無限數量的未來對象(java.util.concurrent.Future)。Java併發:是否取消他們需要收集垃圾的期貨?
但是我擔心在某個時候內存不足。
問題的夫婦在這裏:
您需要最終刪除對Future
的任何引用,以便它們被垃圾收集。通常的做法是維護Future
的集合並定期檢查isDone()
是否返回true
。如果是這樣,任務已完成並且可能會清除對其的引用。如果您擔心堆積一些可能安全中斷的長時間運行的任務,則需要撥打Future
上的cancel()
並刪除/清空可能存在的任何對其的引用。
一般來說,構建一個可能會遇到無限增長的系統總是一個壞主意。如果未完成Future
對象的數量變得太大,則應在系統中的其他位置應用反壓。
未必一定是「一旦未來完成,它就不會被引用到任何地方」。例如,參考它的客戶可以在任何時候通過get()
方法請求結果。因此,JVM需要保留Future
直到所有這些外部引用都被刪除。當Future
「完成」(即完成其任務或被取消)時,線程池中的引用將被刪除。
感謝您指出這一點。但是,我使用的是executorService而不是ThreadPoolExecutor。而ExecutorService似乎沒有'purge()'方法。 –
謝謝!並且ExecutorService被傳遞給我的代碼,並通過在該ExecutorService上調用submit()來創建期貨。該執行者服務即使完成,仍將繼續參照期貨。我不認爲有辦法告訴executorService清除已完成的期貨:(。 –
)ExecutorService將一直完成時不會持有通過submit()提交的任務的引用。如果在運行程序中有其他地方提到'Future',可以關注這個問題 –
Thanks @ andrew-bissell! –