android面试(18)-Android ANR与OOM异常

xiaoxiao2021-02-28  9

从这篇开始,接下来的几篇博客将会对android的异常与性能优化进行分析,今天先说ANR异常;

ANR异常

1.什么是ANR异常?

Application Not Responding,程序无响应

2.原因:

在主线程中做了耗时操作

说到这里,总结一下Android里哪些操作是在主线程中:

(1)Activity的所有生命周期回调

(2)Service默认执行在主线程

(3)BroadCastReceiver的onReceiver回调

(4)没有使用子线程的looper的handler的handlerMessage(),post(Runnable)方法

(5)AsyncTask的回调,除了donInBackground方法,其他都是在主线程

3.如何解决

(1)使用AsyncTask处理耗时操作

(2)使用Thread/HandlerThread提高优先级

(3)使用handler来处理工作线程的耗时任务

(4)Activity的onCreate和onResume回调中尽量避免耗时代码

OOM异常

1.什么是OOM异常:

Out of memory 内存溢出

2.原因

当前占用的内存+申请的内存资源超过Dalvik虚拟机的最大内存

(1)cursor没有关闭

(2)调用registerReceiver后没有UnRegisterReceiver

(3)inputStream/outputStream流等没有及时关闭

(4)没有及时调用bitmap.recycle()方法

3.相关概念

内存溢出:OOM

内存抖动:短时间创建大量对象,然后再次释放,触发GC

内存泄露:进程中对象未被引用,但间接引用到其他对象,使GC无法对其起作用

4.解决办法:

(1)有关bitmap

图片显示:比较常见的一种情况是,在显示缩略图时,不要去请求网络加载大图;

及时释放内存:及时调用recycle方法

这里有一个小点:Bitmap的构造方法都是私有的,所有对象的创建都是通过BitmapFactory来创建,而在BitmapFactory创建Bitmap对象时,会调用jni方法,也就是本地方法,所以,给bitmap分配内存时,其实是有两部分的,一个是java内存,还有一部分是C,也就是本地的内存,java内存GC是可以回收的,而C部分的内存,GC是无法回收的,所以必须调用bitmap.recycle()方法来及时释放内存;

public void recycle() { if (!mRecycled && mNativePtr != 0) { if (nativeRecycle(mNativePtr)) { // return value indicates whether native pixel object was actually recycled. // false indicates that it is still in use at the native level and these // objects should not be collected now. They will be collected later when the // Bitmap itself is collected. mNinePatchChunk = null; } mRecycled = true; } } private static native boolean nativeRecycle(long nativeBitmap);图片压缩:对Bitmap进行合理的压缩,这里是用inSampleSize属性进行压缩 BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; bm = BitmapFactory.decodeFile(Environment .getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera/test.jpg", options); Log.i("wechat", "压缩后图片的大小" + (bm.getByteCount() / 1024 / 1024) + "M宽度为" + bm.getWidth() + "高度为" + bm.getHeight());inBitmap高级属性:在android3.0开始,系统在BitmapFactory.Options里引入了inBitmap机制来配合缓存机制。如果在载入图片时传入了inBitmap那么载入的图片就是inBitmap里的值。这样可以统一有缓存和无缓存的载入方式。inBitmap属性可以告知bitmap的decode解码器,使用以及存在的内存区域,不用重新分配内存;

捕获异常:捕获的异常是Error属性,oom是一个错误,不是一个异常;

(2)其他方法:

ListView的优化方法:

(A)复用contentView

(B)对于大图控件要采用lru(最近最少使用)机制去缓存bitmap

(C)监听滚动时间,在滑动时不要加载图片;

避免在onDraw方法里面执行对象的创建

谨慎使用多进程

转载请注明原文地址: https://www.6miu.com/read-1600176.html

最新回复(0)