在最近作的工程中發現加載的圖片太多或圖片過大時常常出現OOM問題,
經常使用的解決方案以下幾種:
一:在內存中加載圖片時直接在內存中作處理,如:邊界壓縮
二:動態回收內存java
三:優化Dalvik虛擬機的堆內存分配
四:自定義堆內存大小函數
使用邊界壓縮的狀況下間接的使用了軟引用來避免OOM優化
private Map> map = new HashMap>();
public void getBitmap(String path) {
Options bitmapFactoryOptions = new BitmapFactory.Options();
// 下面這個設置是將圖片邊界不可調節變爲可調節
bitmapFactoryOptions. inJustDecodeBounds = true;
bitmapFactoryOptions. inSampleSize = 5;
Bitmap bitmap1 = BitmapFactory. decodeFile(path, bitmapFactoryOptions);
int outWidth = bitmapFactoryOptions. outWidth;
int outHeight = bitmapFactoryOptions. outHeight;
float imagew = 150;
float imageh = 150;
int yRatio = ( int) Math. ceil(outHeight / imageh);
int xRatio = ( int) Math. ceil(outWidth/ imagew);
if (yRatio > 1 || xRatio > 1) {
if (yRatio > xRatio) {
bitmapFactoryOptions. inSampleSize = yRatio;
} else {
bitmapFactoryOptions. inSampleSize = xRatio;
}
}
bitmapFactoryOptions. inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory. decodeFile(path, bitmapFactoryOptions);
//軟引用
SoftReference srf = new SoftReference(bitmap );
map.put(path, srf);
}code
使用邊界壓縮的狀況下間接的使用了軟引用來避免OOM,但你們都知道,這些函數在完成decode後,最終都是經過java層的createBitmap來完成的,須要消耗更多內存,若是圖片多且大,這種方式仍是會引用OOM異常。
能夠採用下面更測底的方式避免OOM:
public static Bitmap readBitMap(Context context, int resId) {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt. inPreferredConfig = Bitmap.Config. RGB_565;
opt. inPurgeable = true;
opt. inInputShareable = true;
// 獲取資源圖片
InputStream is = context.getResources().openRawResource(resId);
return BitmapFactory. decodeStream(is, null, opt);
}
//顯式調用GC來回收內存
if (bitmap .isRecycled()== false){
bitmap.recycle();
System.gc ();
}遊戲
對於Android平臺來講,其託管層使用的Dalvik JavaVM從目前的表現來看還有不少地方能夠優化處理,好比咱們在開發一些大型遊戲或耗資源的應用中可能考慮手動干涉GC處理,使用 dalvik.system.VMRuntime類提供的setTargetHeapUtilization方法能夠加強程序堆內存的處理效率。固然具體 原理咱們能夠參考開源工程,這裏咱們僅說下使用方法: 代碼以下:
private final static float TARGET_HEAP_UTILIZATION = 0.75f;
VMRuntime.getRuntime().setTargetHeapUtilization( TARGET_HEAP_UTILIZATION );圖片
自定義咱們的應用須要多大的內存,這個好暴力哇,強行設置最小內存大小,代碼以下:
private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;
//設置最小heap內存爲6MB大小
VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE);內存