Android内存溢出 (oom)实战
作者今日备受oom煎熬,最后眼睛都盯出花来了才搞定。痛定思痛,决定写一片文章来帮助后人,顺便吊念一下苦逼的过去。
检查篇:
遇到oom一定不能慌,决不能一出来oom就上网查然后一通乱改。相反你要冷静下来看看是谁惹的祸!
不冤枉好人
oom异常有这样的特性:
- 报错的地方不一定是元凶
- 有至少一个地方消耗了大量内存
消耗的内存没有回收
第一点需要特殊解释下:
比如说Android给了你50M内存,当“元凶A”消耗49M内存后不动了,其他操作(B)又消耗了1.1M内存,Android这时候就会在B那报oom的错,说没有资源了。于是B就成了替罪羊。
找出元凶
这是一个痛苦的过程,但为了过大的读者的身心健康,我必须找到一个方便的方法。这面这句放在Application中,可以监控你应用的内存变化。接着一个个去试吧(-.-)。
new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Logs.d(TAG,"最大可用内存:"+Runtime.getRuntime().maxMemory()/1024/1024+"m");
Logs.d(TAG,"已获取内存:"+Runtime.getRuntime().totalMemory()/1024/1024+"m");
Logs.d(TAG,"已获取内存的未使用内存:"+Runtime.getRuntime().freeMemory()/1024/1024+"m");
}
}
}).start();
已知元凶
- activity中引用了超过本身生命周期的对象
- 引入的图片过大或者过多,亦或两者兼有
- gifview的jar包(作者就是这个)
解决办法:
- activity中引用了超过本身生命周期的对象
去掉引用:
变量A.close(); //不同的对象,方法不一样。比如:clear,finish一下
变量A=null; //保险起见(有些对象必须。。) 引入的图片过大或者过多,亦或两者兼有
可尝试用矩阵缩放图片/** * 获得缩略图 * @param index * @param zoom * @return */ private Bitmap getDrawable(int index, int zoom) { if (index >= 0 && index < imagePathes.size()) { String path = imagePathes.get(index); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; int mWidth = options.outWidth; int mHeight = options.outHeight; int s = 1; while ((mWidth / s > itemw * 2 * zoom) || (mHeight / s > itemh * 2 * zoom)) { s *= 2; Logs.d(TAG ,"------->s="+s); } options = new BitmapFactory.Options(); options.inSampleSize = s; options.inPreferredConfig = Config.ARGB_8888; Bitmap bm = decodeFile(path, options); if (bm != null) { int h = bm.getHeight(); Logs.d(TAG, "------->h="+h); int w = bm.getWidth(); Logs.d(TAG,"------->w="+w); float ft = (float) ((float) w / (float) h); float fs = (float) ((float) itemw / (float) itemh); int neww = ft >= fs ? itemw * zoom : (int) (itemh * zoom * ft); int newh = ft >= fs ? (int) (itemw * zoom / ft) : itemh * zoom; float scaleWidth = ((float) neww) / w; float scaleHeight = ((float) newh) / h; Matrix matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); bm = Bitmap.createBitmap(bm, 0, 0, w, h, matrix, true); return bm; } } return null; }
- gifview的jar包(作者就是这个)
换个显示gif的jar包吧。
android-gif-drawable-master //百度一下就好