- 浏览: 296663 次
- 性别:
- 来自: 南京
文章分类
最新评论
-
ggwang:
谢谢分享!
如何释放Ubuntu多余的空间?如何给Ubuntu扩容(install inside windows)? -
allenshao:
只有放枪咯~~~~~
Google Group Android Developers 无法打开的问题 -
malong26:
也打不开~~~
Google Group Android Developers 无法打开的问题 -
songshuang:
一直喂它会一直吃是不?
用你的鼠标逗逗它 -
allenshao:
现在基本上用免费的VPN,缺点是限流量。
如何访问appspot网站?
Dalvik虚拟机支持垃圾收集,但是这不意味着你可以不用关心内存管理。你应该格外注意移动设备的内存使用,在上面内存空间是受到限制的。在这篇
文章里面,我们来看看Android SDK里面的一些内存剖析工具(profiling tools)是如何帮助我们修整应用程序的内存使用。
一些内存使用问题是很明显的,例如,如果在每次用户触摸屏幕的时候应用程序有内存泄露,将会有可能触发OutOfMemoryError,最终程序崩溃。另外一些问题却很微妙,也许只是降低应用程序和整个系统的性能(当高频率和长时间地运行垃圾收集器的时候)。
必要的工具:
Android SDK提供了2个主要的剖析应用程序内存使用情况的工具:DDMS里的一个分页Allocation Tracker和heap
dumps。Allocation
Tracker是很有用的,特别是当你想得到程序在一定的时间里内存的分配情况的一种感性认识的时候。但是它不能给你任何关于程序heap总体情况的任何
信息。关于Allocation Tracker的更多信息,请看文章Tracking Memory Allocations
。文章剩下的内容将把重点放在heap dumps,它是更强大的内存分析工具。
一个heap dump就是一个程序heap的快照,它保存为一种叫做HPROF的二进制格式。Dalvik用的也是类似的格式,但是不完全一样。这里是Java的HPROF工具
。有很多方法去生成一个运行时应用程序的heap dump。其中一种就是使用在DDMS里边的Dump HPROF file按钮。如果想产生更精确的dump数据,可以在程序中使用android.os.Debug.dumpHprofData()
方法。
分析heap dump,你可以使用一些标准的工具比如jhat 或者Eclipse Memory Analyzer(MAT) 。不过,首先你需要把.hprof文件从Dalvik格式转换成J2SE HPROF格式。你可以使用Android SDK提供的hprof-conv工具。例如:
- hprof-conv dump.hprof converted-dump.hprof
调试一个内存泄露实例:
在Dalvik运行时里边,程序员不能显式地分配和释放内存,所以这里的内存泄露跟c和c++里面的不同。在你的代码里边,内存泄露就是你保留了一个并不再需要的类对象的引用。有时候仅仅一个引用就会阻碍gc对一大堆对象的回收。
我们来过一个实际的例子,Android SDK里面提供的范例程序Honeycomb Gallery sample app 。它是一个photo gallery程序,用来演示一些新的Honeycomb API的使用。(下载和编译这些代码,请看这些命令 。)我们会有意地加入一个内存泄露在程序里边,然后来演示如何调试它。
想象一下我们想修改程序让它从网络下载图片。为了让它更具备灵活性,我们可以考虑实现一个缓存,保存最近查看过的图片。我们可以对ContentFragment.java做一些小的修改来达到这个目的。在class顶部,我们增加一个新的静态变量:
- private static HashMap<String,Bitmap> sBitmapCache = new HashMap<String,Bitmap>();
这里就是我们保存缓存的地方。现在我们可以修改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);
- }
我已经在这里故意引入了一个内存泄露的问题:我们把图片加入了缓存但是从来没有移除他们。在真实的应用里,我们可以会用某种方法来限制缓存的大小。
在DDMS里检查heap的使用情况
Dalvik Debug Monitor Server(DDMS)是主要的Android调试工具之一,也是ADT Eclipse plug-in 的一部分,独立的程序版本也可以在Android SDK的根目录下的tools/下面找到。关于DDMS更多的信息,请参考使用DDMS 。
我们来使用DDMS检查这个应用的heap使用情况。你可以使用下面的两种方法启动DDMS:
- from Eclipse: click Window > Open Perspective > Other... > DDMS
- or from the command line: run
ddms
(or./ddms
on Mac/Linux) in thetools/
directory
在左边的面板选择进程com.example.android.hcgallery,然后在 工具条上边点击Show heap updates按钮。这个时候切换到DDMS的VM Heap分页。它会显示每次gc后heap内存的一些基本数据。要看第一次gc后的数据内容,点击Cause GC按钮:
我们可以看到现在的值(Allocated列)是有一些超过8MB。现在滑动相片,这时看到 数据在增大。因为只有仅仅13个相片在程序里边,所以泄露的内存只有这么大。在某种程度上来说,这时最坏的一种内存泄露,因为我们没法得到 OutOfMemoryError来提醒我们说现在内存溢出了。
生成heap dump
我们现在使用heap dump来追踪这个问题。点击DDMS工具条上面的Dump HPROF文件按钮,选择文件存储位置,然后在运行hprof-conv。在这个例子里我们使用独立的MAT版本(版本1.0.1),从MAT站点下载 。
如果你使用ADT(它包含DDMS的插件)同时也在eclipse里面安装了MAT,点击“dump HPROF”按钮将会自动地做转换(用hprof-conv)同时会在eclipse里面打开转换后的hprof文件(它其实用MAT打开)。
用MAT分析heap dumps
启动MAT然后加载刚才我们生成的HPROF文件。MAT是一个强大的工具,讲述它所有的特性超出了本文的范围,所以我只想演示一种你可以用来检测 泄露的方法:直方图(Histogram)视图。它显示了一个可以排序的类实例的列表,内容包括:shallow heap(所有实例的内存使用总和),或者retained heap(所有类实例被分配的内存总和,里面也包括他们所有引用的对象)。
如果我们按照shallow heap排序,我们可以看到byte[]实例在顶端。自从Android3.0(Honeycomb),Bitmap的像素数据被存储在byte数组里 (之前是被存储在Dalvik的heap里),所以基于这个对象的大小来判断,不用说它一定是我们泄露掉的bitmap。
右击byte[]类然后选择List Objects > with incoming references。它会生成一个heap上的所有byte数组的列表,在列表里,我们可以按照Shallow Heap的使用情况来排序。
选择并展开一个比较大的对象,它将展示从根到这个对象的路径--就是一条保证对象有效的链条。注意看,这个就是我们的bitmap缓存!
MAT不会明确告诉我们这就是泄露,因为它也不知道这个东西是不是程序还需要的,只有程序员知道。在这个案例里面,缓存使用的大量的内存会影响到后面的应用程序,所以我们可以考虑限制缓存的大小。
使用MAT比较heap dumps
调试内存泄露时,有时候适时比较2个地方的heap状态是很有用的。这时你就需要生成2个单独的HPROF文件(不要忘了转换格式)。下面是一些关于如何在MAT里比较2个heap dumps的内容(有一点复杂):
- 第一个HPROF 文件(using File > Open Heap Dump ).
- 打开 Histogram view.
- 在Navigation History view里 (如果看不到就从Window > Navigation History找 ), 右击histogram 然后选择Add to Compare Basket .
- 打开第二个HPROF 文件然后重做步骤2和3.
- 切换到Compare Basket view, 然后点击Compare the Results (视图右上角的红色"!"图标)。
总结
这本篇文章里面,我展示了Allocation Tracker和heap dumps是如何给你一种对程序内存使用的感性认识。我也展示了Eclipse Memory Analyzer(MAT)可以帮助追逐我们程序里面的内存泄露问题。MAT是一个强大的工具,我也仅仅触碰了一些皮毛,如果你想学习更多内容,我建议读 一些下面的文章:
- Memory Analyzer News : Eclipse MAT project的官方博客。
- Markus Kohler的Java Performance blog有很多有用的文章, 包括 Analysing the Memory Usage of Android Applications with the Eclipse Memory Analyzer and 10 Useful Tips for the Eclipse Memory Analyzer .
发表评论
-
AOSP source code build error: Virtual memory exhausted: Cannot allocate memory
2014-01-02 15:47 1333Sometimes compiling certain thi ... -
What is the purpose of different Android partitions
2014-01-02 09:57 700-- Boot partition stores the An ... -
Android Kitkat ART vs. Dalvik & Impacts for end-users
2013-12-08 19:00 795What's ART? ART is Google's 2- ... -
error: gnutls_handshake() falied when you sync chip code in ubuntu
2013-11-30 19:47 881gnutls package is broken, worka ... -
unix2dos dos2unix
2013-03-04 20:12 766sudo aptitude install tofrodos ... -
How to make resources added in frameworks/base/core/res/res
2013-02-23 10:19 10511) add the new id to your xml 2 ... -
JDK6 installed in Ubuntu
2012-11-10 15:23 810按照网上的方法apt-get并不成功,我这里采用的方法是手工安 ... -
Android source sync问题汇总(since 2012)
2012-11-04 16:00 17961. [repo init] fetch address is ... -
Android Partitions Explained: boot, system, recovery, data, cache & misc
2012-09-06 16:17 1072Unless you have been using your ... -
Android IPC AudioFlinger binder实例
2012-06-20 13:32 983一篇 android 的 IPC 机制 binder ... -
Eclipse Android project name有错误, source tree无红叉解决办法
2012-06-07 13:22 1280linux: Window -> Preference ... -
Android内核开发的几个常用命令
2012-02-23 15:29 985在android源码的根目录下执行: . build/env ... -
MTP (Media Transfer Protocol) Introduction
2012-02-07 14:46 2284微軟制訂了一套名 ... -
Why is Android laggy, while iOS, Windows Phone 7, QNX, and WebOS are fluid?
2011-12-12 17:55 1008The Root Cause It’s not GC p ... -
Writing Native Code for Android Systems
2011-09-26 17:53 780Writing Native Code for Android ... -
Android JNI 使用的数据结构JNINativeMethod详解
2011-09-13 10:26 854Andoird 中使用了一种不同传统Java JNI的方 ... -
Android property system
2011-08-25 15:11 1307属性系统是 android 的一个重 ... -
Android boot process stub
2011-07-20 10:08 0Android's boot up process is su ... -
Android boot process stub
2011-07-20 10:07 925Android's boot up process is su ... -
OpenFrameworks + kinect + Android
2011-06-20 15:29 1413How to make: 1.Setup ofxAndr ...
相关推荐
Android应用程序内存泄漏的分析.pdf
Android应用程序内存泄漏的分析[整理].pdf
纪喜才:Android应用程序内存管理优化.pptx
Android应用程序中的内存泄漏与规避方法
Android应用程序如何避免内存泄漏以及如何检查泄漏原因
这个PPT讲Android应用程序进程的启动和回收,主要涉及到Zygote进程、System Server进程,以及组件管理服务ActivityManagerService、窗口服务WindowManagerService,还有专用驱动Low Memory Killer。通过了解Android...
在Android里,程序内存被分为2部分:native和dalvik,dalvik就是我们普通的Java使用内存,分析堆栈的时候使用的内存。我们创建的对象是在这里面分配的,对于内存的限制是 native+dalvik 不能超过最大限制. Android ...
Android开发已经成为移动开发热门领域,Android应用程序中内存使用的问题却经常容易被忽视,部分开发者对Java垃圾回收机制认识模糊,使得内存泄漏成为Android应用开发中十分隐秘但又确实存在的应用安全问题,对内存...
Android 会同一系列核心应用程序包一起发布,该应用程序包包括 email 客户端, SMS 短消息程序,日历, 地图,浏览器,联系人管理程序等。所有的应用程序都是使用 JAVA 语言编写的。 应用程序框架 开发人员也可以...
《Android移动应用开发(第3版)卷Ⅰ:基础篇》涵盖了Android开发从概念、技术到市场推广应用的全部主题,内容包括Android平台概览、Android应用程序设计精髓、Android用户界面设计精髓、Android应用程序设计精髓、...
在组织上,《Android系统源代码情景分析(含CD光盘1张)》将上述内容划分为初识Android系统、Android专用驱动系统和Android应用程序框架三大篇。初识Android系统篇介绍了参考书籍、基础知识以及实验环境搭建;...
目前市场占有率很高,而Android应用开发则是通过使用Android软件开发套件(Android Software Development Kit,简称Android SDK)的工具和技术,制作各种Android应用程序。 基本上,Android应用程序可以分为本地应用...
Unity调用Android查看当前app占用内存信息,系统可用内存大小及系统内存大小,FPS的显示,帮助对游戏进行性能优化
1.2 Android应用程序参考书籍 1.3 下载、编译和运行Android源代码 1.3.1 下载Android源代码 1.3.2 编译Android源代码 1.3.3 运行Android模拟器 1.4 下载、编译和运行Android内核源代码 1.4.1 下载...
用于Android应用程序的外部记录器库。 您可以将日志保存在应用程序的任何组件中(活动,服务,片段)。 即使退出应用程序或关闭设备,数据也将存储在内存中。
HTC资深工程师的经验总结,包括两大部分: (1) 提升应用程序性能, 从以下四方面介绍:framework, UI, I/O, Scrolling (2) 内存, 介绍了Android平台内存衡量的工具,以及防止内存泄露的最佳实践
android的内存泄露问题,教你如何避免内存泄露 优化程序
1.1.3 Android应用程序框架 1.2 OMS介绍 1.2.1 OPhone介绍 1.2.2 Widget介绍 1.3 小结 第2章 Android开发环境搭建 2.1 Android开发准备工作 2.2 开发包及其工具的安装和 配置 2.2.1 安装JDK和...
罗升阳-Android源码情景分析,本书将上述内容划分为初识Android系统、Android专用驱动系统和Android应用程序框架三大篇。初识Android系统篇介绍了参考书籍、基础知识以及实验环境搭建;Android专用驱动系统篇介绍了...