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都会给清理干净,内存也不再一直上升了,而是上下浮动。至此,悬案结案了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值