2013-11-22 91 views
1

我寫了一些代碼,我可能需要創建一個無限數量的未來對象(java.util.concurrent.Future)。Java併發:是否取消他們需要收集垃圾的期貨?

但是我擔心在某個時候內存不足。

問題的夫婦在這裏:

  1. 是否JVM知道,一旦未來已經完成,它沒有被任何地方refernced,因此可享有GC(即使在其中創建它的線程仍然活着和跑步)?
  2. 理想情況下,我不想跟蹤這些期貨本身。但是,如果我確實保留這些期貨的參考資料並定期對它們進行取消,那麼它們是否可以用於GC?

回答

3

您需要最終刪除對Future的任何引用,以便它們被垃圾收集。通常的做法是維護Future的集合並定期檢查isDone()是否返回true。如果是這樣,任務已完成並且可能會清除對其的引用。如果您擔心堆積一些可能安全中斷的長時間運行的任務,則需要撥打Future上的cancel()並刪除/清空可能存在的任何對其的引用。

一般來說,構建一個可能會遇到無限增長的系統總是一個壞主意。如果未完成Future對象的數量變得太大,則應在系統中的其他位置應用反壓。

未必一定是「一旦未來完成,它就不會被引用到任何地方」。例如,參考它的客戶可以在任何時候通過get()方法請求結果。因此,JVM需要保留Future直到所有這些外部引用都被刪除。當Future「完成」(即完成其任務或被取消)時,線程池中的引用將被刪除。

+0

謝謝!並且ExecutorService被傳遞給我的代碼,並通過在該ExecutorService上調用submit()來創建期貨。該執行者服務即使完成,仍將繼續參照期貨。我不認爲有辦法告訴executorService清除已完成的期貨:(。 –

+0

)ExecutorService將一直完成時不會持有通過submit()提交的任務的引用。如果在運行程序中有其他地方提到'Future',可以關注這個問題 –

+0

Thanks @ andrew-bissell! –

0

你見過this的問題嗎?

未來的計算完成後,您無法再取消它。 我不知道確切的上下文,但有一個建議是跟蹤期貨,取消你想要的或者需要取消的,並且呼叫清除執行者將他們從工作隊列中移除。

希望它有幫助。

+0

感謝您指出這一點。但是,我使用的是executorService而不是ThreadPoolExecutor。而ExecutorService似乎沒有'purge()'方法。 –