2010-06-30 54 views
7

我正在檢查內存,試圖通過hprof轉儲查找最終的內存泄漏。com.android.internal.policy.impl.PhoneLayoutInflater有時留在內存中(hprof轉儲)

我發現有時候,當我通過後退按鈕離開活動時(活動結束),活動仍然保留在內存中,但它只有兩個GC根,這似乎不是很強'雖然。

這是我的活動流程/ I點擊和測試方式:

A,B,C爲活動。

1)A - >乙 - >(返回)甲

2)做一個HPROF轉儲與以下結果:

乙仍處於存儲器, B活動的GC根中的唯一元素是:

com.myapp.android.activity.directory.B

  • mContext com.android.internal.policy.impl.PhoneLayoutInflater的

    • android.app.ContextImpl的mLayoutInflater [堆棧本地]

      • [局部變量]的java .lang.Thread [Thread]「main」
  • mOuterContext的android.app.ContextImpl [堆棧本地]

    • java.lang.Thread中[線程]的[局部變量] 「主」

(Thread「內主「似乎是UI線程)

繼續從A:

3) - 」ç - >(BAC k到)甲

4)做一個HPROF轉儲結果如下(如預期):

B不在存儲器再,C不在存儲器中了,只有A

現在我的問題是: 這個PhoneLayoutInflater是從哪裏來的/爲什麼當它從B返回到A時仍然保留在內存中,但是在繼續進行到C並返回到A之後它會消失。

顯然PhoneLayoutInflater是用於充氣的意見,我意識到它的目的。我只是不明白爲什麼它會通過主UI線程中的GC根保存在內存中。

當我檢查上面列出

[局部變量]的java.lang.Thread的 [主題]「主

的GC根它將具備以下條件:

  • m.u.Thread of com.myapp.android.activity.main。A [Stack Local]
    • ....
      • 此$ 0 $ android.view.inputmethod.InputMethodManager ControlledInputConnectionWrapper [JNI全局]

的方式我稱之爲活動乙並且來自A的C經由常規的startActivity(intent)

爲什麼活動A的主UI線程會以某種方式與活動B相關並引用?

+0

http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html可能是相關的。 – fadden 2010-06-30 18:13:04

+0

感謝您的鏈接,但我已閱讀過很多次。沒有提及另一個活動的UI線程,我也不知道這個「$ 0的android.view.inputmethod.InputMethodManager $ ControlledInputConnectionWrapper [JNI Global]」來自哪裏。這是奇怪的事情。 – 2010-06-30 18:22:18

+0

我有與phoneLayoutInflater相同的問題。在過去,我使用反射消除了android中的這些內存異常(通常與列表有關),但我不知道這到底是什麼原因導致了這種情況,或者我可以在沒有啓動應用程序的情況下反射到null。將增加一個賞金。 – 2011-03-09 19:23:00

回答

0

這是我最終做的,但我仍然不高興我正在使用反射來解決這個問題。任何人??

public static boolean ReleaseActivityContext(Context context) 
{      
    LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
    Class<?> i = inflater.getClass(); 

    try 
    {  
     Field f = i.getSuperclass().getDeclaredField("mContext"); 
     f.setAccessible(true); // prevent IllegalAccessException 
     f.set(inflater, null); // can cause IllegalAccessException 
     return true;  
    } 
    catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 
    return false; 
} 
0

我有同樣的問題,我使用了Eclipse MAT分析HPROF,我花了8小時,最後我發現,有一些簡單的規則可循。

不要讓一個 上下文活動長期引用(一 活動的參考應該有什麼樣的生活 週期活動本身)

嘗試使用背景的應用 代替的上下文活動。

避免非靜態內部類在 活動,如果你不控制自己的 生命週期,使用靜態內部類 ,使弱引用裏面的 活動。

遵循以下步驟: enter image description here

然後點擊...

你可以看到對象的原因留在記憶 enter image description here

現在修改你的代碼,看看爲什麼有一些參考資料時,有沒有需要他們的存在的存在。然後在返回鍵按下取消那些參考和中提琴..世界將再次看起來很美:) :)

+0

我正在使用Eclipse MAT來分析內存 – 2011-03-16 14:46:08

+0

Aizaz,感謝您的回覆,我沒有時間嘗試您發佈的解決方案。運行良好?據我所知,沒有任何活動性上下文,但只有當我傳遞任何上下文時才使用app context。btw - 這是一篇關於Android on memory分析的新博客文章:http://android-developers.blogspot.com/2011/03/memory-analysis-for-android.html – 2011-03-25 03:34:41

+0

我正在使用yourkit.com進行內存分析,也是很好的工具,但不是免費的。 – 2011-03-25 03:35:29