標籤:
1. Android2.x及以下的系統最佳化:
Bitmap被解碼後的像素被儲存在Native Heap中,
Dalvik Heap有個external計數,記錄了Bitmap所佔用的記憶體。
當 Dalvik Allocated + External Allocated + new Allocated>= 允許分配最大值時,就會引發OutOfMemoryError異常,
銷毀的時候必須要調用recycle()。BitmapFactory.Options參數,隱藏了inNativeAlloc屬性,
可以使Bitmap的記憶體不算在Dalvik Heap中。
2. Android 3.x及以上的系統最佳化:
Bitmap被解碼後的像素被儲存在Java Heap,只要Bitmap沒有
被引用,在記憶體緊張時就會被回收,不需要主動調用recycle。只有當 Dalvik Allocated + new Allocated>= 允許分配最大值時,
就會引發OutOfMemoryError異常,BitmapFactory.Options參數,有個inPurgeable屬性,開啟後像素會儲存在Native Heap中,
有個缺陷就是,在Bitmap顯示時如何Native Heap中沒有緩衝,又需要重新解碼,會阻塞UI線程。
可以在jni層通過AndroidBitmap_lockPixels把解碼後的記憶體鎖住,防止被回收,然後在不適用時通過AndroidBitmap_unlockPixels(env, zBitmap)
來取消加鎖(可以參考Fresco的實現)
3. AndroidManifest.xml設定largeHeap=true
ActivityManager.getMemoryClass()可以擷取dalvik.vm.heapgrowthlimitd的值,單位MB
ActivityManager.getLargeMemoryClass()可以擷取dalvik.vm.heapsize的值,單位MB
Runtime.getRuntime().maxMemory()擷取當前VM的最大可用記憶體,單位Byte
4. 對Bitmap的建立封裝統一的入口
使用LruCache減少Bitmap頻繁的create
盡量使用decodeStream代替decodeResource decodeFile
使用catch,當發生OOM時,主動執行GC,降低圖片灰階值,再次建立
根據view的實際大小來解碼相應大小的bitmap
5. 防止記憶體泄露
避免使用生命週期長的對象應用生命週期短的對象(使用 static關鍵字,單例中的引用)
注意註冊與反註冊配對使用
使用leakcanary工具來動態追蹤記憶體泄露,使用MAT來靜態分析記憶體泄露。
6.不要頻繁的分配大記憶體對象,不適用的對象提前置NULL,提前回收。
Android 防止OOM最佳化