一、原因
1、内存泄漏导致
频繁的内存泄漏将会引发内存溢出;
2、占用内存较多的对象
保存了多个耗用内存较多的对象(如Bitmap);
加载超大的图片;
二、解决方案
1、内存泄漏导致的OOM,可参考Android常见问题之内存泄漏
2、加载超大图片造成的OOM解决方案:
1)等比例缩小图片
使用setImageBitmap或setImageResource或BitmapFactory.decodeResource设置大图时,这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。
public static Bitmap scaleImage(Bitmap bitmap, int newWidth, int newHeight) {
if (bitmap == null) {
return null;
}
float scaleWidth = (float) newWidth / bitmap.getWidth();
float scaleHeight = (float) newHeight / bitmap.getHeight();
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
2)对图片采用软引用,及时地进行recycle()操作
虽然系统能够确认Bitmap分配的内存最终会被销毁,但是由于它占用的内存过多,所以很可能会超过java堆的限制。因此,在用完Bitmap时要及时的recycle掉。recycle并不能确定立即就会将Bitmap释放掉,但是会给虚拟机一个暗示:“该图片可以释放了”。
SoftReference<Bitmap> bitmap;
bitmap = new SoftReference<>(pBitmap);
if(bitmap != null){
if(bitmap.get() != null && !bitmap.get().isRecycled()){
bitmap.get().recycle();
bitmap = null;
}
}
3)避免XML的重复加载
因为单个页面横竖屏切换多次后,会出现OOM的情况。
所以当页面布局中存在较大的图片时,应该去除xml中相关设置,改在程序中设置背景图;
ImageView imageView= (ImageView) findViewById(R.id.image_test);
imageView.setBackground(getDrawable(R.mipmap.ic_launcher));
或者直接把xml配置文件加载成view 再放到一个容器里,然后直接调用 this.setContentView(View view)