正确使用Context
一般Context造成的内存泄漏,几乎都是当Context销毁的时候,却因为被引用导致销毁失败,而Application的Context对象可以理解为随着进程存在的,所以我们总结出使用Context的正确姿势:
1:当Application的Context能搞定的情况下,并且生命周期长的对象,优先使用Application的Context。
2:不要让生命周期长于Activity的对象持有到Activity的引用。
3:尽量不要在Activity中使用非静态内部类,因为非静态内部类会隐式持有外部类实例的引用,如果使用静态内部类,将外部实例引用作为弱引用持有。
ANR基本分析定位方法
ANR分析主要是Input、Broadcast、Service三种ANR, 对应的时间主要有以下几种:其中后台时间相对长一些,broadcast可以达到60s,但是前台一般最高10s,后台service是20s。
类型 前台 后台
Input 8s 8s
Forground Broadcast 10s 20s
Background Broadcast 10s 60s
Service 10s 20s
定位问题思路是,首先查看anr的进程,类型,cpu占用,iowait等指标
activity、broadcast、还是service,是前台还是后台。
cpu占用是否过高,iowait是否正常,是否是由于整机问题影响
查看线程调用栈,main主线程是由于什么原因导致的anr, 等锁lock,是否死锁? 是否binder卡住了? 是否no focus windows可能是由于进程被杀,搜索是否有window change查看界面切换的影响?wait和notifiy导致的死锁,查看相关代码?其他卡住的地方File、database、sharepreference可以怀疑文件系统等。
引起ANR问题的根本原因,总的来说可以归纳为两类:
• 应用进程自身引起的,例如:
主线程阻塞、挂起、死循环
应用进程的其他线程的CPU占用率高,使得主线程无法抢占到CPU时间片
• 其他进程间接引起的,例如:
当前应用进程进行进程间通信请求其他进程,其他进程的操作长时间没有反馈
其他进程的CPU占用率高,使得当前应用进程无法抢占到CPU时间片
分析ANR问题时,以上述可能的几种原因为线索,通过分析各种日志信息,大多数情况下你就可以很容易找到问题所在了。
进程被杀
android原声机制被杀
当Android系统认为当时已经没有足够的内存来运行新的进程,需要“LowMemory Killer”关闭一些进程来回收内存,它是在Linux内核中实现的。
ActivityManagerService记录每一个进程的优先级,进程的oom_adj值就代表优先级,oom_adj值越高代表该进程优先级越低。
每一个oom_adj对应一个内存警戒值,当系统的可用内存低于某个警戒值时,就杀掉所有大于该警戒值对应的oom_adj值的进程。
SystemUI recenttask被杀 任务管理器清理进程属于用户手动清理,使用removetask方式清理任务管理器列表
一键清理等被杀。