Android(安卓)记录一次内存溢出的查找历程
>>长路漫漫立志行高远,寒夜漆漆心勇敢独行。 --致青春
起因:
前几天客户反映说,app(一个用于显示叫号信息的显示窗口)每天下午6点多会自己退出,具体也不知道是什么原因,我也去现场蹲了几次点儿,也没找到原因。
结果:
经过几天的对app内存分析,终于把问题给找到了,一句话总结:OOM 引起的 app 退出。
过程:
1、猜测引起app退出的诱因:
- 此app更新窗口信息采用的接口轮询模式,1秒刷新一次,就是说,这里会有大量的网络请求;
- app有全天不停止的轮播图,并且图片定时更新;
2、分析app自动退出的原因:
- 异常的情况:我做了全局异常捕获,有异常退出了会自动重启,但现实是app并没有重启,由此推测,肯定不是异常引起的,那就只能是app占用内存过多导致的OOM了;
- 内存泄漏引起的OOM:用 LeakCanary 抓一下有没有泄漏的地方,结果,没有一个泄漏的地方(没想到我写的代码这么优秀,哈哈)。
- 猜测应该就是某个对象一直被创建,并且不释放,由于网络请求是不间断的、频繁的,故而先从网络请求下手。
3、查找过程:
自己用手机测了几天,并且挂着AS的profiler进行了全天内存监控,有发现,app占用的内存在持续上升,并且GC也不会降。
于是dump了一段一段的内存去查找区别,发现rxjava的一个Observer 的类被不停的创建对象,这个类就是网络请求中用于接收请求结果的,这里面我用了 rxjava 的 CompositeDisposable 去管理各个请求,用于页面销毁时取消正在进行的网络请求,但是我这个app的页面就一个,并且不会销毁,于是这个 CompositeDisposable 就存储了大量的 Disposable 对象,这些对象都是要等到页面销毁时才会去清理掉,但是我的页面并不会销毁,于是这个 CompositeDisposable 就一直在飙升的占用内存;
4、处理方法:在 Observer 实现类中记录每个请求的 Disposable,不再等页面销毁时才清理 CompositeDisposable,而是在Observer的几个网络请求结果中对Disposable进行清理,只是从 CompositeDisposable 将 Disposable 清理(delete)了,并不是取消(dispose)请求。
5、测试成果:虽然 Observer 对象在内存仍然有一些,但是每次系统自动GC都会给清理干净,内存也不再一直上升了,而是上下浮动。至此,悬案结案了。
更多相关文章
- android中常见的内存泄漏和解决办法
- android正在运行进程和后台缓存进程的区别
- android内存问题详解--重要
- android网易顶部导航栏demo
- Android(安卓)Volley完全解析(四),带你从源码的角度理解Volley
- Android最佳性能实践(1):合理管理内存
- android注册 登录+修改帐号密码+添加资料+给指定帐号充值
- 总结android中的进程
- Android(安卓)应用开发 之使用LruCache和DiskLruCache来在内存和