在最近作的工程中发现加载的图片太多或图片过大时常常出现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);内存