Android OOM以及GC的一些建議
-
這里有一個不錯的文章在分析內存泄漏。它絕對可以幫助你. http://android-developers.blogspot.com/2011/03/memory-analysis-for-android.html.
-
你是否能保證你的SoftHashMap正常工作?看起來相當復雜。建議使用debugger來確保SoftHashMap中從未超過15個位圖。 MAT也可以幫助你確定有多少位圖出現在內存中。可以調用 cache.put(photoToLoad.url, bmp),來禁用內存緩存,確定否是有問題.
-
Activity leak 如果你只是在相同的activity中滑動發生OOM,這意味著有別的東西leaking 而不是activity 。如果停止/啟動Activity幾次,發現OOM仍然出現。那么查看MAT histogram 可以確定是否Activity leaking
-
當您使用圖像的大小不是很確定時。應該要保證它的完美work,即使是 5m px 這么大的圖像。
-
你可以嘗試只用 HashMap<String, SoftReference<Bitmap>>更換你的SoftReference的實現。這是良好的實現在內存緩存。它判斷對象在內存中是否有足夠的內存。如果內存太少,SoftReference釋放的對象。
-
我推薦使用LinkedHashMap處理in-memory cache.。它有一個特殊的構造迭代在其中的最后一次訪問順序的entry。文檔說,當你有超過15個項目在緩存中,你可以刪除最近最少訪問的項目。
-
如果你要加載更大的圖像,你應該考慮清楚它們有多少內存消耗。如果太多,你可以只緩存他們SD卡,而不是內存中。這樣做的話, 性能可能比較慢,但不會OOM
-
無關OOM。如果你調用clearCache() 在 onLowMemory()方法中。這樣做不是一件好事,因為clearCache()也會刪除SD緩存, 你要知道你要做的是清除內存緩存而不是SD緩存
- hprof-conv dump.hprof converted-dump.hprof
Resource here:
-
Here's an amazing article on analyzing memory leaks. It can definitely help you. http://android-developers.blogspot.com/2011/03/memory-analysis-for-android.html.
-
Are you absolutely sure your SoftHashMap implementation works fine? Looks rather complicated. You can use debugger to ensure SoftHashMap never holds more than 15 bitmaps. MAT can also help you to identify how many bitmaps are there in memory.
You can also comment cache.put(photoToLoad.url, bmp) call. This way you'll disable in-memory caching to identify if it's a cause of a problem or not. -
Yes it may be an Activity leak. You can identify that. If you just scroll around in the same activity and get OOM it means that something else is leaking not activity. If you stop/start activity several times and get OOM it means activity is leaking. Also you can definitely say is activity leaking or not if you take a look at MAT histogram.
-
As you use inSampleSize the image size doesn't matter. It should work fine even with 5mpx images.
-
You could try to replace your SoftHashMap implementation with just HashMap<String, SoftReference<Bitmap>>. Read about SoftReference. It is good for very simple implementation of in-memory cache. It holds objects in memory if there's enough memory. If there's too little memory SoftReference releases objects.
-
I can also recommend you to use LinkedHashMap for in-memory cache. It has a special constuctor to iterate items in the order in which its entries were last accessed. So when you have more than 15 items in cache you can remove least-recently accessed items. As documentation says:
-
You know my implementation was designed with small images in mind, something like 50*50. If you have larger images you should think how much memory they consume. If they take too much you could just cache them to SD card but not to memory. The performance may be slower but OOM would not be a problem any more.
-
Not related to OOM. I can see you call clearCache() in onLowMemory(). Not good because clearCache() also removes cache from SD. You should only clear in-memory cache not SD cache.