Android 应用程序内存泄漏的分析

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Android 应用程序内存泄漏的分析以前在学校里学习Java的时候,总是看到说,java是由垃圾收集器(GC)来管理内存回收的,所以当时形成的观念是Java不会产生内存泄漏,我们可以只管去申请内存,不需要关注内存回收,GC会帮我们完成。呵呵,很幼稚的想法,GC没那么聪明啊,理论及事实证明,我们的Java程序也是会有内存泄漏的。

(一)Java内存泄漏从何而来

一般来说内存泄漏有两种情况。一种情况如在C/C++语言中的,在堆中的分配的内存,没有将其释放,或者是在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉(如指针重新赋值);另一种情况则是在内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)。第一种情况,在Java中已经由于垃圾回收机制的引入,得到了很好的解决。所以,Java中的内存泄漏,主要指的是第二种情况。

(二)需要的工具

1.DDMS—Update heap Gause GC

Heap 是DDMS自带的一个很不错的内存监控工具,下图红色框中最左边的图标就是该

工具的启动按钮,它能在Heap视图中显示选中进程的当前内存使用的详细情况。下图

框中最右边的是GC工具,很多时候我们使用Heap监控内存的时候要借助GC工具,点

击一次GC按钮就相当于向VM请求了一次GC操作。中间的按钮是Dump HPROF file,它

的功能相当于给内存拍一张照,然后将这些内存信息保存到hprof文件里面,在使用我

们的第二个工具MAT的时候会使用到这个功能。

2.MAT(Memory Analyzer Tool)

Heap工具能给我们一个感性的认识,告诉我们程序当前的内存使用情况和是否存在内存

泄漏的肯能性。但是,如果我们想更详细,更深入的了解内存消耗的情况,找到问题所

在,那么我们还需要一个工具,就是MAT。这个工具是需要我们自己去下载的,可以下

载独立的MAT RCP 客户端,也可以以插件的形式安装到Eclipse里面,方便起见,推荐

后者。

安装方法:

A.登录官网/mat/downloads.php

B.下载MAT Eclipse插件安装包(红框所示,当然你也可是选择Update Site在线安装,个人觉得比较慢)

C.安装

在Eclipse里面安装新软件,选择刚才下载的本地安装包进行安装

(三)案例分析

工具准备好了,那就来看看怎么使用。我们以Q+ for Pad为例,看看查找好友功能是否存在内存泄漏。

1.打开 eclipse 并切换到 DDMS 透视图,同时确认 Devices 、 Heap 和 logcat 视图已经打

开了。

2.将Pad设备链接到电脑,并确保使用“ USB 调试”模式链接

3.启动我们的Q+ for Pad应用,此时我们能看到下图所示的情况,Q+ Pad有两个进程

4.选中main进程,点击Update Heap按钮,再点击GC按钮,查看该进程当前堆内存的使用

情况

如何才能知道我们的程序是否有内存泄漏的可能性呢。这里需要注意一个值:Heap视图中部有一个Type叫做data object,即数据对象,也就是我们的程序中大量存在的类型的对象。在data object一行中有一列是“Total Size”,其值就是当前进程中所有Java 数据对象的内存总量,一般情况下,这个值的大小决定了是否会有内存泄漏。可以这样判断:

a) 不断的操作当前应用,同时注意观察data object的T otal Size值;

b) 正常情况下Total Size值都会稳定在一个有限的范围内,也就是说由于程序中的的代

码良好,没有造成对象不被垃圾回收的情况,所以说虽然我们不断的操作会不断的生成很多对象,而在虚拟机不断的进行GC的过程中,这些对象都被回收了,内存占用量会会落到一个稳定的水平;

c) 反之如果代码中存在没有释放对象引用的情况,则data object的T otal Size值在每

次GC后不会有明显的回落,随着操作次数的增多T otal Size的值会越来越大,直到到达一个上限后导致进程被kill掉。

5.输入昵称,查找联系人,在查到的结果中不断向下翻页,最后退出(这个时候程序会不

断的拉取联系人的头像,这是我们要关注的),然后我们点击下GC按钮,手动触发下垃圾回收,结果截图如下,图中红色标记的地方可以看出,执行查找联系人操作后,这两个数值明显增加了,GC操作也无法使之下降,我们可以怀疑,这个操作导致了内存泄漏。

6.使用MAT进一步分析,找到问题的根源。之前我们已经安装了MAT插件,所以这里我

们只要选中main进程,点击Dump HPROF file按钮,就会跳转到MAT视图。在弹出的对话框中选择报告类型,一般选第一个就行。

点击完成后,MAT会自动生成报告,列出几个内存占用比较大的可疑对象,MAT不会明确告诉我们这就是泄露,因为它也不知道这个东西是不是程序还需要的,只有程序员自己知道。图中很明显的占用内存较大的是头像资源,并且当退出查找联系人功能后,这些资源是需要释放的,陌生人的头像我们不需要缓存在内存里面。

点击Domain Tree按钮,可以按包进行分组。点开树形列表,可以更详细的看到类对象占用内存的大小。其中,Shallow Heap表示实例的内存使用总和,Retained Heap表示所有类实例被分配的内存总和,里面也包括他们所有引用的对象。

从生成的数据中,我们发现有一千多个HashMapEntry对象,针对单个HashMapEntry对象继续追踪,最后找到了一个6KB左右的Bitmap,应该就是我们的头像资源。

因此,为了回收内存,我们必须把刚才查找好友保存在内存中的头像资源释放。通过使

相关文档
最新文档