2012-03-29 4 views
1

這是關於線程對象的android應用程序內存泄漏。Android內存泄漏新線程()

我不知道下面的代碼導致內存泄漏,因爲我開始了3年的android程序。

Thread t = new Thread(); 

t不被垃圾收集器檢測到。

問題是我如何從vm內存釋放局部變量t?

我決定嘗試

我做了我的應用程序,它的行爲是下面的代碼按鈕。

for(int i=0;i<1000;i++) 
{ 
    Thread t = new Thread(); 
} 

我預計局部變量t將在某天被釋放。

我用調試模式執行它並打開E-clipse DDMS透視圖。

我選擇我的Android設備(2.3.6)在我的應用程序的線程,並點擊「更新堆」按鈕

所以我可以檢查堆大小和實時分配。

它始於總堆大小5.445MB並分配2.779 MB。

然後我點擊生成1000個線程對象的按鈕。

它改變了堆大小5.508MB和分配3.058 MB。

正如您所知,DDMS透視圖中存在「原因GC」按鈕。

我點了那個按鈕。但分配的內存仍然是3.058MB。

我再次點擊我的按鈕來產生另外1000個線程對象。

我點擊無望的「Gause GC」按鈕。

最終堆大小消失了大約20MB,並導致內存不足異常。

我該如何釋放Thread實例對象?

+0

在大多數情況下,最好使用Executor而不是線程。如果你使用類似cachedThreadPool的東西,它會爲你處理活動的線程。 http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Executor.html – Jave 2012-03-29 08:22:12

回答

1

您正在使用的線程中完成後,調用interupt()

而且我不知道是否有必要,但按照Johannes的建議設置t=null可能是個好主意。

但是,在停止線程之後,由JVM的垃圾收集器處理線程本身的銷燬。

+1

它不起作用.... for(int i = 0; I <1000;我++) \t \t \t \t { \t \t \t \t \t線程t =新主題(); \t \t \t \t \t t.start(); \t \t \t \t \t t.interrupt(); \t \t \t \t \t t = null; \t \t \t \t} – muyoungko 2012-03-29 13:09:44

+0

好吧。這真的沒關係。應該沒有實例需要創建1000個線程。而創建一個線程不會佔用那麼多的內存。 而你創建這麼多線程的事實可能是問題的原因。如果您要創建一個,請插入它並將其設置爲空,那麼機會將從內存中清除。如果沒有,那麼我不相信你會做任何事情。 – Jakar 2012-03-30 07:29:40

+0

這實際上解決了這個問題,我使用12個Thread對象的數組在大約20分鐘內創建了7000個線程。 @muyoungko我注意到你的for循環測試實際上沒有運行或任何東西 - 也許這是問題的一部分...在啓動()後過早調用interrupt()?在我的情況下,我有一個AtomicBoolean(用於多個線程的數組),它告訴我線程已完成 - 然後我在原始Thread對象上中斷(),然後在同一個數組插槽中創建一個新線程。使用此解決方案,內存泄漏消失。 – 2015-03-05 18:02:25

0

我沒有安卓設備來測試它,但我會認爲一個線程需要在它不能被任何變量引用之前被垃圾收集之前去死。

開始嘗試在你的循環線程這樣的:

for(int i=0;i<1000;i++) 
{ 
    Thread t = new Thread(); 
    t.start(); 
    t = null; 
} 
+1

它不起作用 – muyoungko 2012-03-29 09:45:48