Benjy's Blog

Android 应用内存溢出导致应用退出的解决方案

2014-11-11

昨天项目里遇到了一个严重问题,用户在使用一段时间应用之后,便会非常慢,最终导致内存溢出而崩溃,这个问题几乎让我们的一切努力白费。我几乎花了一整天的时间才终于找到了问题所在。问题的原因让我完全意料不到。

在分析原因的时候我使用的是 Eclipse 的 Memory AnalysisTools + DDMS,这套工具真是在关键时候解决了我的大问题。
附上 Memory Analysis 插件的下载地址
只使用DDMS也可以看出在activity切换过程中的内存变化,但是不能并发现问题的具体所在,所以我们需要MAT(Memory AnalysisTools)来分析具体是那个类引发的问题。上图

tool-editor

上图大家应该都看的懂吧,不懂的我简单说一下,也不要嫌弃我啰嗦:

  • 1位置是开始监控 一般在启动应用之后就可以点上来查看记录了
  • 2位置是保存分析到文件,装了Memory Analysis之后便可以直接打开分析界面
  • 3位置是查看内存数值的区域,内存变化的过程基本上就是在这里分析出来的

具体的使用大家可以参考这篇文章 http://www.360doc.com/content/12/1023/14/203871_243274421.shtml,解决问题的过程真的是非常的快乐的,我希望大家也可以通过这个过程get新技能,而不是一味的 copy。

分析的过程我也就不多说了 好多次的分析才找到了问题所在,依然直接说结果:

现在大家在写app的时候通常会使用一个集合来保存整个 Activity。或放在 BaseActivity 里,或放在 Application 里,
然后在退出应用的时候遍历集合逐个调用finish方法,以此来达到退出整个应用,这些方法在网上很多写法,也是大多数人推荐的做法,但我如今碰到的问题就是这里导致的。我的测试结果是,虽然在每个activity的finish方法里把自己从容器里移除自己,但依然因为这个导致activity不能释放,如此循环往复导致了内存溢出。找到了问题所在就好解决多了,就怕有问题自己也摸不到头绪。其实如果自己控制好每个界面的启动和销毁,这样的做法完全是多此一举的,如果你实在想这样做,推荐的是使用广播的方法,在每个 Activity 里面注册一个广播,应用退出的时候通过广播来关闭所有 Activity,不要忘了在 onDestroy 里注销广播哟。

ps

我曾经也深信不疑的使用网上的各种现成的代码,但如今,我想至少应该测试过会再使用才行,不要人云亦云,知其然知其所以然,才能最大的提升自己的能力。感谢项目经理的耐心教导。
另外MAT工具推荐大家都学习一下,特别是大型项目一定要严格控制内存,否则会死的很惨。

Tags: Android