- 浏览: 302100 次
- 性别:
- 来自: 南京
文章分类
最新评论
-
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 1383Sometimes compiling certain thi ... -
What is the purpose of different Android partitions
2014-01-02 09:57 744-- Boot partition stores the An ... -
Android Kitkat ART vs. Dalvik & Impacts for end-users
2013-12-08 19:00 834What's ART? ART is Google's 2- ... -
error: gnutls_handshake() falied when you sync chip code in ubuntu
2013-11-30 19:47 927gnutls package is broken, worka ... -
unix2dos dos2unix
2013-03-04 20:12 798sudo aptitude install tofrodos ... -
How to make resources added in frameworks/base/core/res/res
2013-02-23 10:19 10881) add the new id to your xml 2 ... -
JDK6 installed in Ubuntu
2012-11-10 15:23 856按照网上的方法apt-get并不成功,我这里采用的方法是手工安 ... -
Android source sync问题汇总(since 2012)
2012-11-04 16:00 18381. [repo init] fetch address is ... -
Android Partitions Explained: boot, system, recovery, data, cache & misc
2012-09-06 16:17 1108Unless you have been using your ... -
Android IPC AudioFlinger binder实例
2012-06-20 13:32 1020一篇 android 的 IPC 机制 binder ... -
Eclipse Android project name有错误, source tree无红叉解决办法
2012-06-07 13:22 1318linux: Window -> Preference ... -
Android内核开发的几个常用命令
2012-02-23 15:29 1020在android源码的根目录下执行: . build/env ... -
MTP (Media Transfer Protocol) Introduction
2012-02-07 14:46 2321微軟制訂了一套名 ... -
Why is Android laggy, while iOS, Windows Phone 7, QNX, and WebOS are fluid?
2011-12-12 17:55 1042The Root Cause It’s not GC p ... -
Writing Native Code for Android Systems
2011-09-26 17:53 808Writing Native Code for Android ... -
Android JNI 使用的数据结构JNINativeMethod详解
2011-09-13 10:26 896Andoird 中使用了一种不同传统Java JNI的方 ... -
Android property system
2011-08-25 15:11 1342属性系统是 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 964Android's boot up process is su ... -
OpenFrameworks + kinect + Android
2011-06-20 15:29 1448How to make: 1.Setup ofxAndr ...
相关推荐
标题中提到的是关于“Android应用程序内存泄漏的分析”,这意味着文档的核心内容将集中在分析Android平台下应用程序可能遇到的内存泄漏问题。内存泄漏是Android开发中非常常见且棘手的问题,它发生在一个对象不再被...
### Android应用程序开发知识点详解 #### 一、Android概述 Android是一种基于Linux内核的开源移动设备操作系统,由Google公司和开放手机联盟领导及开发。它主要用于触摸操作的手持设备上,如智能手机和平板电脑等...
【Android应用程序内存泄漏的分析】 在Android应用开发中,内存泄漏是一个重要的问题,因为它会导致应用程序性能下降,甚至可能引发应用崩溃。尽管Java的垃圾回收机制(GC)在一定程度上减轻了程序员对内存管理的...
本文将深入探讨Android应用程序内存管理优化的相关知识点。 首先,我们理解内存优化的重要性。Android系统为每个应用程序分配了一定量的内存资源,如果应用过度消耗内存,可能导致Out of Memory (OOM)错误,使应用...
造成Android应用程序内存泄漏的原因 ##### 1.1 引用未释放造成的内存泄漏 - **注册未取消**:在Android中,如果在活动或服务结束前未取消注册监听器、广播接收者等,即使活动或服务已经结束,但由于外部应用或...
在Android里,程序内存被分为2部分:native和dalvik,dalvik就是我们普通的Java使用内存,分析堆栈的时候使用的内存。我们创建的对象是在这里面分配的,对于内存的限制是 native+dalvik 不能超过最大限制. Android ...
基于静态分析方法的Android应用内存泄漏检测模型 Android 应用程序的内存泄漏问题较为常见,主要是由于部分开发人员对 Android 内存管理机制理解模糊所致。为了解决内存泄漏的检测问题,首先需要分析 Android 系统...
这个压缩包"88个经典Android应用程序打包下载(源代码).zip"包含了88款Android应用的源代码,为开发者提供了宝贵的参考资料。这些应用可能涵盖各种类型,如社交、游戏、工具、音乐、视频等,通过研究它们,开发者...
此文档不仅覆盖了基本的Android应用程序开发流程,而且还提供了具体的案例分析和技术指导,使读者能够快速理解和应用这些知识。 #### 二、Android系统应用环境搭建 **2-1 UBUNTU10.10上编译ANDROID源码** - **2-1...
本文将深入探讨Android应用程序架构的关键组件、设计模式以及最佳实践,基于提供的压缩文件"Android应用程序架构.rar"中的文档内容进行详细阐述。 首先,Android应用程序由多个组件构成,主要包括Activity、Service...
【Android应用程序“计算器”】 Android应用程序“计算器”是基于谷歌Android操作系统开发的一款实用工具,它为用户提供基础到高级的计算功能,以便在移动设备上进行数学运算。Android平台以其开放性和丰富的开发...
《Android应用程序开发(第二版)代码》是一个针对Android平台应用开发的资源集合,主要涵盖了在Android Studio环境下构建、设计和优化应用程序的各种技术。这个压缩包包含的文件是开发者学习和实践Android编程的...
Android Studio作为Google官方推荐的Android应用程序开发集成开发环境(IDE),其功能强大且不断更新,是每一个Android开发者必备的工具。 本书涵盖了从Android Studio的基础操作到高级特性的全面内容,包括但不...
这个压缩包包含了88个经典Android应用程序的源代码,是学习和研究Android开发不可多得的资源。 首先,我们可以从这些源码中学习到基础的Android组件使用,如Activity、Service、BroadcastReceiver和ContentProvider...
《Android应用程序开发与典型案例》是一本深入探讨Android应用开发的专业书籍,它涵盖了从基础到高级的各类主题,旨在帮助开发者全面掌握Android平台上的应用构建技巧。这本书提供了丰富的案例,通过实例解析来阐述...
Android应用程序由多个组件构成,包括Activity、Service、Broadcast Receiver和Content Provider等。这些组件共同协作来完成特定的任务。 **5.2 应用程序包含的各个文件** 应用程序中的每个组件都需要对应的XML...
【Android应用程序详细结构介绍】 Android应用程序的开发通常在Eclipse集成开发环境中进行,它提供了便捷的工具来创建和管理Android项目。"HelloWorld"作为入门级的程序,可以帮助初学者理解Android应用程序的基本...
在Android应用程序开发中,内存泄漏是一个严重的问题,它可能导致应用性能下降、系统资源浪费甚至应用程序崩溃。虽然Java的垃圾收集器(GC)自动处理大部分内存管理,但在Android中,由于其特殊的生命周期和对Context...