Android: Unknown “Bitmap” cause by 'mGlow' causing memory leak

weixin_34236497發表於2016-02-18

Android: Unknown “Bitmap” cause by 'mGlow' causing memory leak


1. 新建一個android工程,只有一個listview,通過MAT工具檢視記憶體情況莫名其妙多了>200K記憶體空間(android4.4 Genymotion)。


1517703-a3ec64cb126215ee.png
hprof檔案


2.通過右鍵“List Objects"->"with incoming references"可以檢視"byte[281880]"誰使用。


1517703-5c5765c1ed8c1dea.png
with incoming references

3.原來是ListView中的mEdgeGlowBottom和mEdgeGlowTop在使用"byte[281880]",檢視ListView原始碼,發現是在AbsListView中定義mEdgeGlowBottom和mEdgeGlowTop,用於overscroll時顯示的效果。


1517703-7dc4e723cac4c328.png
AbsListView,setOverScrollMode函式

4.android4.4原始碼EdgeEffect類中載入資源R.drawable.overscroll_edge,R.drawable.overscroll_glow,至此"byte[281880]"的源頭找到了。


1517703-6c7e4bfddccd976d.png
android4.4原始碼EdgeEffect

5.找到資源源頭,如何去掉"byte[281880]"記憶體佔用呢?

1)AbsListView的setOverScrollMode函式是建立EdgeEffect物件的地方,只要想辦法把mOverScrollMode設定為OVER_SCROLL_NEVER。

2)View的建構函式中會呼叫setOverScrollMode,所以需要在xml中設定屬性,之前在程式碼中設定了,結果無效。


1517703-0b913b1807816dab.png
view建構函式呼叫setOverScrollMode

6.配置ListView屬性。


1517703-e1a1ab38bd3b9764.png
ListView配置overScrollMode="never"

7.至此mGlow bitmap記憶體佔用就沒有了。如果不需要overScrollMode效果的話可以去掉。在android5.0原始碼中發現EdgeEffect實現方式變了,不是載入Drawable,而是使用Paint進行繪製的。


1517703-e160af353b920a95.png
android5.0原始碼EdgeEffect

總結:不需要的功能就disable,減少記憶體佔用;能不使用圖片的地方就不使用,用程式碼實現,減小記憶體佔用,apk空間佔用。

相關文章