最近接手的一个老项目,功能比较繁杂,是运行在安卓pos机上面的收银系统,基本需要应用整天在前台使用,对系统稳定性要求较高,不同于一般app。

今天做了内存方面的检测


首先我们用电脑连接设备,用cmd执行adb的内存检测的命令

adb shell dumpsys meminfo best.DianJiaPos

后面的best.DianJiaPos是包名,要改成自己的


执行后会显示如下信息:

使用Android studio 的Analyzer Task分析解决activity内存泄漏问题

使用Android studio 的Analyzer Task分析解决activity内存泄漏问题

这里面需要关心的有:HeapSize(堆总大小)HeapAlloc(已用大小)HeapFree(剩余可用)

分为Native Heap和Dalvik Heap,这里我们只关心Dalvik Heap

另外还有一些应用相关信息:Views,Activitys等,可以统计到已经存在的view和activity个数


那么,怎么判断一个activity是否发生泄漏?

这里有个简单的办法,先使用以上命令,获取activity个数,然后在应用内执行一些可用关闭activity的操作,比如切换用户,退出登录,或者一些界面的返回键finish等

activity执行finish或onDestroy之后,再次执行以上命令,获取内存信息,看activity个数,如果个数没有减少,这个activity就很可能发生泄漏了


下面是我的MainActivity界面

使用Android studio 的Analyzer Task分析解决activity内存泄漏问题使用Android studio 的Analyzer Task分析解决activity内存泄漏问题

应用逻辑是,从LoginActivity中登录,登录成功进入MainActivity,然后在MainActivity中有切换用户功能,点击之后会销毁MainActivity进入LoginActivity

此时的activity数量应该是1,如果多了就很可以,可能是有其他的功能逻辑,继续持有MainActivity的引用,导致MainActivity资源无法释放


在我进行多次上述操作之后,获取内存信息,发现activity数量已经达到十几个,显然存在activity泄漏

接下来我们使用Android studio 的Analyzer Task进行分析


首先,进行可能产生内存泄漏的操作

之后,进入androidstudio开发界面,下方切换到monitors,点击下面的保存的图标

使用Android studio 的Analyzer Task分析解决activity内存泄漏问题

使用Android studio 的Analyzer Task分析解决activity内存泄漏问题

稍等片刻,androidstudio保存好hprof文件后会自动打开

使用Android studio 的Analyzer Task分析解决activity内存泄漏问题

使用Android studio 的Analyzer Task分析解决activity内存泄漏问题


打开后界面如上,右侧有一个Analyzer Task

点开它,点击蓝色箭头,会自动帮我们分析内存泄漏

使用Android studio 的Analyzer Task分析解决activity内存泄漏问题使用Android studio 的Analyzer Task分析解决activity内存泄漏问题


如图,检测到了MainActivity

选中之后,下方会显示相关信息,这里提醒大家调试时候一定要关掉混淆,否则,这里检测出来的代码变量,都是混淆后的,很难找到目标


使用Android studio 的Analyzer Task分析解决activity内存泄漏问题使用Android studio 的Analyzer Task分析解决activity内存泄漏问题


如上图,Analyzer Task自动帮我们检测出可能的泄漏处,并用蓝色字体显示


使用Android studio 的Analyzer Task分析解决activity内存泄漏问题使用Android studio 的Analyzer Task分析解决activity内存泄漏问题


点开之后如图所示,这里解释一下引用关系

上图的结构,表示MainActivity被PrnDspA1088这个类的s变量引用

而s变量又被CashierFragment的dsp变量引用


那么接下来看看CashierFragment的代码

private static PrnDspA1088 dsp = null;
......

dsp = new PrnDspA1088(getActivity());
发现dsp是一个静态变量,而创建dsp时,又把activity传进去了,于是导致静态变量间接引用activity,activity不能释放造成内存泄漏


常见的内存泄漏原因除了static引用之外,还有资源未释放/服务未解绑/EventBus未注销/TimeTask未停止等

大家使用这些的时候一定不要忘记释放资源。






相关文章:

  • 2021-06-17
  • 2021-11-04
  • 2021-07-25
  • 2021-04-03
  • 2021-11-24
猜你喜欢
  • 2021-07-30
  • 2021-07-17
  • 2022-12-23
  • 2022-12-23
  • 2021-09-10
  • 2021-10-23
相关资源
相似解决方案