Android中的ANR和OOM

时间:2022-07-27 15:32:21
内存溢出的几点原因
1.资源释放问题

程序代码的问题,长期保持某些资源,如Context,Cursor,IO流的引用,资源得不到释放造成内存泄露
2.对象内存过大问题
保存了多个内存过大的对象,造成内存超出限制
3.static关键字的使用问题
static是Java中的一个关键字,当用来修饰成员变量时,它的生命周期是很长的,如果用来来引用一些资源耗费
过多的实例,这时就需要谨慎了。
针对 static 的解决方案
1) 应该尽量避免 static 成员变量引用资源耗费过多的实例,比如 Context。
2) Context 尽量使用ApplicationContext,因为Application的 Context 的生命周期比较
长,引用它不会出现内存泄露的问题。
3) 使用 WeakReference代替强引用。比如可以使用WeakReference<Context>mContextRef;
4.线程导致内存溢出
线程产生内存泄露的主要原因是线程生命周期的不可控。

如何合理使用内存
1.注意资源回收,像数据库,输入输出流,定位操作这样的对象,要在使用完及时关闭
2.少使用静态变量,因为系统将静态变量的优先级设定的很高,会最后回收。
3.注意大图片的缩放,如果载入的图片很大,要先经过自己程序的处理,降低分辨率等。
4.动态注册监听
5.减少使用动画


ANR,怎样避免ANR问题?
在Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框,这个对
话框称作应用程序无响应。用户可以选择让程序继续运行,但是,它们在使用你的程序是,并不希望每次都要处
理这个对话框。因此,在程序里对响应性能的设计很重要,这样,系统不会显示ANR给用户。
ANR一般有三种类型
1.keyDispatchTimeout(5 seconds)--主要类型
按键或触摸事件在特定时间内无响应
2.BroadcastTimeout(10 seconds)
BroadcastReceive在特定时间内无法处理完成
3.ServiceTimeout(20 seconds)
Service在特定的时间内无法处理完成
超时的原因一般有两种:
(1)当前的事件没有机会得到处理(UI线程正在处理前一个事件没有及时完成或者looper被某种原因阻塞住)
(2)当前的事件正在处理,但没有及时完成

UI 线程尽量只做跟 UI 相关的工作,耗时的工作(数据库操作,I/O,连接网络或者其他可能阻碍UI线程的操作)

放入单独的线程处理,尽量用Handler来处理UI thread和thread之间的交互。