2010-08-16 53 views
0

我有一個Android應用程序,我使用HashMap,其中我保持我的線程(值)每個執行任務(Runnable)。爲了確定線程我使用字符串作爲鍵。只要他們執行通常不太長的任務,線程就會一直存在。問題是它們在完成並從HashMap中刪除後似乎從未被GC釋放過(並且它們不在其他地方引用)。如果我創建了我的應用程序的轉儲,那麼在應用程序的整個生命週期中,我的內存中的任務數量就與我一樣多。試圖使用HashSet來代替,但結果相同。內存泄漏與Android上的HashMap/HashSet

在代碼中,我開始跟他們這幾行:

Thread image_fetch_thread = new Thread(new ImageFetchTask(image_url, this)); 

this.running_image_fetch_threads.put(image_url, image_fetch_thread); 

image_fetch_thread.start(); 

,並在某一時刻後,他們成爲去除:

this.running_image_fetch_threads.remove(image_url); 

爲什麼GC不喜歡收集的?

+0

我只是做了android系統中的幾件事情,但你真的確定你應該保持地圖的線程?在桌面Java中,我會說這是一個明確的代碼惡意。 – bwawok 2010-08-17 19:00:23

回答

0

你有多確定你是其實將他們從HashMapHashSet中刪除?創建轉儲時,該集合的size()是什麼?

+0

我使用remove(key)來刪除按鍵的線程,甚至確保每次調用size()時都調用GC。所以我認爲這個刪除至少有效。 – georgij 2010-08-17 11:07:46

1

你確定你的線程正在完成嗎?即使你在HashMap中刪除了對你的Thread的引用,如果它沒有真正完成,它也不會被GCed。運行方法必須完成才能發生。

+0

是的,他們肯定會完成(他們很簡單,沒有循環)。它們在從集合中移除時還沒有完成,因爲刪除是從線程本身觸發的,作爲完成之前的最後一個操作。這可能是一個問題嗎? – georgij 2010-08-17 10:35:32

+0

不,只要將它們從地圖中移除,一旦線程完成,它們應該有資格收集。你能發佈一些示例代碼嗎? – Robin 2010-08-17 13:44:41