android内存溢出排查

好一阵子没写技术博客了,最近几个月由于新工作上确实太忙了,还是怀念去年那种写博客的节奏,几乎每周都会写一篇,每天的快节奏写博客能让自己的整个人都静下来,也是最舒服,最踏实的时刻,真心很享受这种很“宅”的生活方式,刚好今天难得可以有闲暇时间,所以将断了很久的文章继续,好了,费话不多说,正入今天的正题:

如标题所示,今天要研究的话题是做每个商业应用都会遇到的一个头疼而又棘手的问题,那就是内存泄露(通常看到的Out Of Memeory Exception)的问题,尤其像手持设备上的android应用更加容易出现,由于基本上每个公司的产品都是敏捷式的开发,所以开发周期都是非常紧,往往在写代码时很难照顾到性能,优化相关的问题,而这些问题都是在产品上线之后才会暴露出来,可能大牛们会说:"这是你们编码经验不够的结果,一个高素质的程序员写出来的代码可以避免这种问题的产生",也许是这样,但是在实际商业项目中开发应该很难做到这点,其一,不是完全由一个人开发,而是一个团队多人开发;其二,不同的人的编码习惯完全不一样,所以写代码时的全局观很难把握;其三团队里面的人员层次也不尽相同;所以这种内存的瓶颈几乎每个项目都会遇到,网上有N多避免内存泄露出现的策略,但是一个项目的代码量都是比较大的,要从中找到内存泄露点是很困难的,所以,借助于工具来定位是最合适的,今天主要是介绍利用工具来查找实际项目中内存泄露点,并最终来解决它。

MAT(Eclipse Memory Analyzer),我想做JAVA开发的人应该都或多或少都听说过,是一款非常强大的内存泄露分析工具,今天也就是利用它来解决我们项目中内存溢出的问题,MAT里面的功能非常强大,说实话我也不是太熟悉所有强大的功能,但是只要工具能为我所用,能解决实际工作中的问题,只用它中的小小功能那也知足已,毕境不是靠这工具为生,当然在使用它之前得首先有一些了解,建议可以先看一下网上的这篇博文:http://www.blogjava.net/rosen/archive/2010/05/21/321575.html 说实话这篇博文刚看是有些难懂,但是多看几遍还是或多或少能理解一些的,看完之后,对于它的简单使用就可以用到我们的项目中来了,关于怎么安装MAT,及它的使用这里就不介绍了,网上的文章一大堆,下面正式开始利用它来解决自己项目中的问题。

首先先以动画的形式来展现一下真实项目中内存溢出的出现场景【要来就来实际的,虚的模拟一概摒弃】

最后崩溃的异常日志我想不用猜地球人也都知道,肯定是内存溢出了,但我们还是来具体看一下这个具体的异常:

这是一款游戏市场类的APP,装在模拟器上进行的内存测试,可见就是简单的几个操作,就出现了内存溢出崩溃的问题,这对于用户来说是非常致命的,而从实际的日志来看,就是图片加载这一块造成的,也是非常常见导致内存溢出的场景,我想拿到这个异常之后正常人的第一反应肯定是去代码中去定位报错的行,我也不例外,但是最后事实告诉我,这种解决内存的思路是错误的,这个在之后会得到论证,另外在开始解决内存之前,先来简单说明下报错具体行中的ImageLoader类,这不是我自己写的,而是从网上用的三方图片加载的很强大的开源组件,地址:https://github.com/nostra13/Android-Universal-Image-Loader,而进入它的官网去查看,原来很多大型有名的Android App都用的它:

我说明这个类库的目的,是证明图片加载这一块应该是非常成熟稳定,而且内存的问题绝对也已经考虑到了,不然也不会有这么多项目将它集成到自己项目中来,当然在遇到这个内存错误时,报出这个组件的代码出问题了,不怀疑它是不可能的,我是因为知道事实的结果了所以才知道跟它没关系。关于这些结论暂且先不用关心,之后等解决了这个问题之后会回过头来进行总结,这样再遇到类似的问题就不会走错路了,好了,实验继续:

【说明】:在看下面操作之前,一定得首先去了解MAT的使用,博文开头也已经介绍了网址,这边重在总结思路,而不是教大家怎么用MAT这个工具哈。

接下来真正开始定位原因了,一款商业项目怎么来定位到底是什么造成内存溢出呢?答案还是交给我们强大的MAT了,

首先生成.hprof进行分析:

具体生成步骤,这里就不一一说明了,但是有一个值得思考的问题:如何在Android程序发生内存溢出崩溃之时抓拍下当时的内存状态?

网上说可以在运行配置里加上参数:-XX:+HeapDumpOnOutOfMemoryError:

但是我是从Android官网下的集成IDE,里面貌似没有这个选项,所以,这种非常好的方式就暂时不研究了,如果可以配置的话最好配置一下,以便在内存溢出报错时则会生成分析文件,方便进行内存跟踪。

 

根据提示来分析泄露点并逐一尝试解决:

 

参考博文:

  1. http://wenku.baidu.com/link?url=qFz2D7SWlsFZovSU5RWXbZejEEBUuYZgue7kPs6qWKc0IoHesdzgIvrAFSpOJjaHU_LDcCaBPkTdtadawDfAG7MFpBg93i0zI4ysNUaJtT_
  2. http://www.blogjava.net/rosen/archive/2010/05/21/321575.html
  3. http://mikewang.blog.51cto.com/3826268/1254306/

简单理解Java GC与幽灵引用

http://developer.51cto.com/art/200906/128189.htm

posted on 2014-04-26 23:34  cexo  阅读(378)  评论(0)    收藏  举报

导航