android应用内存分析,Android应用程序内存分析-Memory Analysis for Android Applications
Android应用程序内存分析
原文链接:http://android-developers.blogspot.com/2011/03/memory-analysis-for-android.html
Dalvik 自带有内存回收机制,但这并不意味程序员可以忽略内存的管理。在移动设备上,内存比较紧缺,因此你应当对内存的使用更加小心。在本文中,我们将介绍如何使用android SDK中的内存分析工具来对应用程序的内存使用情况进行分析。
有些内存问题是显而易见的。例如,如果应用程序在每次用户触摸屏幕时都会泄漏一些内存,那么该应用将很快因为 OutOfMemoryError的异常而崩溃。另外一些则更加隐蔽,它们有可能只会导致应用程序和整个系统变慢(垃圾回收器频繁和长时间进行垃圾回收)
调试工具
在android SDK中提供了两种内存分析的方法:内存申请跟踪(以下用Allocation tracker) 和 堆转储(以下用heap dump)。Allocation tracker可以帮我们了解到一段时间内,应用对内存的申请情况,但是它不能提供任何有关应用程序堆的信息。更多有关内存申请追踪的信息请看 Tracking Memory Allocations。接下来的篇幅中我们将重点关注一种更加强有力的分析工具——heap dump的使用。
Heap dump是应用程序堆的的快照,它存放在一种特定格式(HPROF)的二进制文件中。Dalvik使用类似于HPROF的格式来保存heap dump。生成应用程序的heap dump的方法有多种,DDMS中的head dump按钮就提供了生成heap dump的功能。如果想要对heap dump的生成有更加精细的控制,可以在程序中使用android.os.Debug.dumpHprofData()来生成。
常用的分析heap dump的工具有jhat 和 Eclipse Memory Analyzer (MAT) 。在分析之前,我们需要将Dalivk heap dump文件的格式转换成J2SE 标准的HPROF格式。android SDK中提供了hprof-conv工具来进行这个转换。命令如下:
hprof-conv dump.hprof converted-dump.hprof
例子:如何分析内存泄漏
在Dalivk环境中,程序员不能显式的申请和释放内存,因此内存不会像在C/C++中的那样真正泄漏。在这种情况下,内存泄漏往往指的是程序中保存了无用的对象的引用,有时保存一个对象的引用,而这个对象又拥有大量其他对象的引用,那么这些对象将都无法被垃圾回收器回收。
让我们看android SDK中的一个示例程序Honeycomb Gallery sample app。这是一个用来展示如何使用android Honeycomb 中的新API的照片库应用(如何下载和编译这个应用的代码,请看介绍)。我们将小心的在这个应用的代码中加入一个内存泄漏的bug,以讲述如何调试这样的问题。
假如我们想修改这个应用,让其具有从网络上下载图片的能力。为了提升体验,我们决定实现一个缓存以存储最近收到的图片,我们通过对ContentFragment.java文件进行一些小的修改来实现这个想法。首先在这个类的顶部加上一个静态的变量
private static HashMapsBitmapCache = new HashMap();
这个变量将保存我们想要缓存的图片,现在我们修改updateContentAndRecycleBitmap() 加入检查存储和存入缓存的功能
void updateContentAndRecycleBitmap(int category, int position) {
if (mCurrentActionMode != null) {
mCurrentActionMode.finish();
}
// Get the bitmap that needs to be drawn and update the ImageView.
// Check if the Bitmap is already in the cache
String bitmapId = "" + category + "." + position;
mBitmap = sBitmapCache.get(bitmapId);
if (mBitmap == null) {
// It's not in the cache, so load the Bitmap and add it to the cache.
// DANGER! We add items to this cache without ever removing any.
mBitmap = Directory.getCategory(category).getEntry(position)
.getBitmap(getResources());
sBitmapCache.put(bitmapId, mBitmap);
}
((ImageView) getView().findViewById(R.id.image)).setImageBitmap(mBitmap);
}
这里,我故意留下了一个memory leak的问题:我们将Bitmap添加到cache但是却从来不从cache中删除它们。在真正的应用中,往往会对cache的大小进行一个限制。
使用DDMS来分析内存使用情况
DDMS是android最主要的一个调试工具,它是ADT插件的一部分,同时在android SDK的tools/ directory目录下也有一个独立的版本。更对关于DDMS的信息,请看Using DDMS
让我们使用DDMS来分析内存使用情况。DDMS有两种启动方式:
从Eclipse:点击Window > Open Perspective > Other... > DDMS
从命令行:在tools/ directory中执行ddms命令
在左边的面板里选择进程com.example.android.hcgallery,然后点击工具栏上的Show heap updates按钮,之后切换到DDMS中的VM Heap页。这里显示了堆内存的基本状态信息,这些信息每次GC时更新。点击Cause GC按钮可以触发第一次更新。
可以看到,我们使用了8MB多一点的内存,现在滑动相册,看到这个数字会变大。由于应用中总共只有13張图片,因此我们不会无限制的泄漏内存。从某种意义上来说,这是一种最糟糕的泄漏,因为我们永远也不会收到OutOfMemoryError的异常来帮助我们发现这个问题。
创建一个heap dump
让我们使用heap dump来定位这个问题。点击中DDMS工具栏上的Dump HPROF按钮,选择一个保存路径,然后运行hprof-conv处理这个文件。在这个例子中,我将使用MAT的独立应用版本(版本号1.0.1),下载链接MAT download site
如果你正在使用ADT并且Eclipse中已经安装了MAT插件,点击dump HPROF按钮,工具将会自动对HPROF文件进行格式转换,然后直接在Eclipse中使用MAT打开转换后的HPROF文件。
使用MAT分析heap dump
启动MAT,打开我们转换过的HPROF文件。MAT是个强大的工具,拥有很多功能。在这篇文章中,我只介绍一种使用它来分析内存问题的方法:Histogram view。Histogram view显示了堆中所有类的列表,我们可以将列表中这些类按照其实例(object)的个数的多少排序(包括按照浅堆中实例的个数和深堆中实例的个数)
如果我们按照浅堆排序,我们可以看到byte[]类型排在第一位,这是因为在android3.0中bitmap的像素点数据都保存在byte数组中(之前它们都没有被保存在dalik的堆空间中),基于这些数组的大小,我们可以断言,这些数组就是我们泄漏的bitmap内存的一部分。
在列表中右击byte[]类型,在弹出菜单中依次选择List Objects > with incoming references,可以看到,在之前视图中我们点击的类型对应的所有浅堆中的byte array对象都被列了出来。
选择其中一个比较大的对象,点击箭头查看下拉列表中的内容,这里我们可以看到这个对象的整条引用链,其中可以找到我们的bitmap cache。
MAT不能明确的告诉我们哪里发生了泄漏,因为它并不知道这些对象是否还在使用——仅仅只有程序员知道这一点。在这个例子中,缓存占用了应用程序大量的内存,因此在这种情况下,我们应该考虑对cache的大小进行限制。
使用MAT对heap dump进行比较
有时比较两个不同时间点的heap dump对我们分析内存泄漏问题是很有帮助的。首先,我们需要生成两个heap dump文件(别忘记使用 hprof-conv进行转换)
接下来我们可以使用MAT进行比较了(过程稍稍有些复杂)
打开第一个HPROF 文件(使用 File > Open Heap Dump)
打开Histogram view
在Navigation History view中(如果找不到使用 Window > Navigation History打开), 对其中的histogram条目右击,然后选择Add to Compare Basket.
重复2~3步骤,打开第二个HPROF文件
切换到Compare Basket 页,点击Compare the Results按钮(这页右上角的红色按钮)
总结
在本文中,我展示了如何通过Allocation Tracker 和 heap dumps 这两个工具来
更好的认识
应用内存的使用情况有。我也展示了如何使用MAT来追踪应用中的内存泄漏问题。MAT是个强大的工具,而我在这里仅仅只是提到了它的皮毛。如果你想要了解更多相关内容,我建议你阅读下面的文章
Memory Analyzer News: Eclipse MAT官方blog
Markus Kohler 的java性能分析博客有很多有用的文章, 包括 Analysing the Memory Usage of Android Applications with the Eclipse Memory Analyzer 和10 Useful Tips for the Eclipse Memory Analyzer.
android应用内存分析,Android应用程序内存分析-Memory Analysis for Android Applications相关推荐
- java 减少内存_java-减少应用程序内存占用
>如果经常重复使用具有自然语言频率的字符串,请不要对同一字符串使用新的对象实例. private Map sharedStrings = new HashMap<>(). publi ...
- php采集分析,PHP采集程序原理分析篇
由于需要,要写一个简单的PHP采集程序,照例是到网上找了一堆教程,然后照猫画虎,可是发现网上的教程全是似是而非,没有一个真正能用的.苦想了几天,终于弄明白了里面的道理.在这里写出来,请高手指正. 采集 ...
- linux c 代码分析工具,编程达人 分享几款Linux 下C/C++程序内存泄漏检查工具
1.内存管理是否正确(因为这个程序本身开辟很多内存空间进行缓存管理,同时这个程序程序本身就是基于C/C++开发的,内存管理机制一直是程序员头痛的东西) 2.程序的健硕性如何(服务器任何程序的基本要求就 ...
- Wince程序内存和存储内存
Wince 下的内存实际上是分为三个部分的. 先说这几部分的名字,对象存储, 系统内存,程序内存. 准确来讲,应该用下面公式说明Wince内存 = 系统内存 + (对象存储 + 程序内存).这里德内存 ...
- oracle 内存分析工具,IDE 中的分析工具
IDE 中的分析工具 Oracle Solaris Studio IDE 提供的交互式图形分析工具可用于检查在 IDE 内部运行的项目的性能.分析工具使用 Oracle Solaris Studio ...
- Linux 下几款程序内存泄漏检查工具
Linux 下几款程序内存泄漏检查工具 chenyoubing | 发布于 2016-07-23 10:08:09 | 阅读量 93 | 无 写这篇博客的原因呢是因为自己在编写基于Nginx磁盘缓存管 ...
- Unix下C程序内存泄露检测工具:valgrind的安装使用
Valgrind是一款用于内存调试.内存泄漏检测以及性能分析的软件开发工具. Valgrind的最初作者是Julian Seward,他于2006年由于在开发Valgrind上的工作获得了第二届Goo ...
- 《小猫猫大课堂》三轮5——动态内存管理(通讯录动态内存化)
宝子,你不点个赞吗?不评个论吗?不收个藏吗? 最后的最后,关注我,关注我,关注我,你会看到更多有趣的博客哦!!! 喵喵喵,你对我真的很重要. 目录 前言 动态内存产生的原因 动态内存函数 malloc ...
- 【Android 逆向】修改运行中的 Android 进程的内存数据 ( 使用 IDA 分析要修改的内存特征 | 根据内存特征搜索修改点 | 修改进程内存 )
文章目录 一.使用 IDA 分析要修改的内存特征 二.根据内存特征搜索修改点 三.修改进程内存 一.使用 IDA 分析要修改的内存特征 在前的博客 [Android 逆向]逆向修改游戏应用 ( 分析应 ...
最新文章
- linux putty xshell vi 小键盘无法使用的解决方法
- c 语言文字输出函数,c/c++语言中文字输出函数总结
- OpenGL编程指南1:OpenGL简介
- VTK:BackfaceCulling背面剔除用法实战
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口 6...
- 数据结构之图的存储结构:邻接多重表
- 设计一个扩展自抽象类geometricobject的新的triangle类_面向对象设计原则之开放封闭原则(开闭原则OCP)...
- 《Cisco防火墙》一8.7 通过NAT规则定义连接限制
- 【数据结构和算法笔记】:图的深度优先搜索(DFS)
- 鲍尔默先生,请拿出证据
- ad17如何删除3d实体_3D打印的过程/流程
- pandas.series.tolist()函数结构及用法
- 贪心算法3: 会议安排
- python卡方检验计算pvalue值_Python数据科学:卡方检验
- linux dot命令,DOT语言使用笔记(1)
- 遗传图谱的可视化(比mapchart更强大)
- js如何修改对象的padding属性
- 全国计算机等级考试二级Java全真模拟
- NLP(三十九)使用keras-bert实现完形填空及简单的文本纠错功能
- NET Framework合集(官方)