Android Performance(7) Investigating Your RAM Usage

 转载请注明:http://blog.csdn.net/liaoqianchuan00/article/details/23599453

我们在开发移动设备上得App的时候,必须考虑RAM的使用情况,虽然Android有垃圾回收机制,但是这并不意味着你不需要关心内存分配和释放的问题。为了提供优秀的用户体验,你的程序不必消耗没有必要的内存。

 

虽然你已经有了一些管理APP内存的经验,但是在开发过程中你还是会或多或少的遇到一些内存泄露和其他的内存问题,这就需要我们能分析我们的app内存使用情况,下面我们讲解怎么进行分析。

 

Log信息

分析你的app内存使用情况最简单的地方就是查看Dalvik的log信息。你可以在logcat中查看到这些信息。

每次GC回收发生的时候,logcat都会打印下面这些信息:

D/dalvikvm:<GC_Reason> <Amount_freed>, <Heap_stats>,<External_memory_stats>, <Pause_time>

 

1.       GC Reason  GC发生的原因和GC回收的类型。原因有以下几种:

 

GC_CONCURRENT

Heap即将填满导致并发的GC回收

GC_FOR_MALLOC

当heap已经被占满了,这个时候你还尝试分配内存,促使GC发生,这时,系统会强制停掉你的程序。

GC_HPROF_DUMP_HEAP

当你创建一个HPROF文件去分析heap的时候触发GC。

GC_EXPLICIT

显示的调用GC回收,比如你调用了gc()(你应该避免这样做,应该使用系统自己的gc机制)

GC_EXTERNAL_ALLOC

这个只会发生在API10和以下的版本(新版本都只会在Dalvik heap上分配)。其他内存触发的GC,比如存在NIO byte buffers中得像素数据。

 

2.       Amount freed:回收的内存大小。

3.       Heap stats:空闲的内存百分比以及(现有对象大小)/(heap大小)

4.       External memory stats:(API10及以下的其他内存分配大小)/(GC将发生的大小)。

5.       Pause time:暂停时间,越大的heap暂停时间越久,并发的会显示两个pause:一个是回收开始,老外一个是回收快结束的时候。

 

例子:

D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65%free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms

 

当有很多个这个类似的语句的时候,查看heap stats(比如上例中得3571k/9991k)是否持续增长,如果是,你可能就存在内存泄露的问题。

 

查看Heap情况

想要简单的了解你的程序的内存使用情况,可以实时的在DDMS中监控heap的使用情况:

1.       打开DDMS

2.       选中你的进程

3.       点击update heap

4.       在右边面板中选择heap标签栏

heap视图展示了heap使用的基本情况,会在每个GC后自动更新,查看变化情况,点击Cause GC按钮。

 

持续使用你的app,并且查看gc后heap的分配情况,可以帮助你找到某个分配过多内存的操作,可以帮助你分析哪里可以减少内存分配和释放资源。

 

跟踪分配情况

为了缩小内存问题的范围,你需要用到Allocation Tracker来更好的分析有问题的内存分配。

 

1.       打开DDMS

2.       选中你的进程

3.       在右边的面板中选中Allocation Tracker 标签页

4.       点击start tracking。

5.       持续和你的程序交付

6.       点击Get Allocations来更新分配情况。

这个表里面显示了最近的分配情况。点击其中的一行可以查看stack trace。它向你展示了分配的对象类型,在哪个线程中被分配,在哪个类以及哪个文件的哪一行。

 

例如,一些app常常会在每个draw中创建一个Paint,我们可以将这个object编程global成员来解决这个问题。

 

Capturing a Heap Dump

Heap dump就是heap中对象的一个快照,以二进制的形式保存,叫做HPROF。这个文件提供了你的app heap的全部使用情况,所以当你在刚才的步骤中发现问题时,你可以使用heap dump来查找问题原因。

 

打开DDMS

选中你的app进程

点击Dump HPROF file,如下图所示

在弹出的窗口中填入文件名和保存位置,点击save。


如果你想要更精确的在某个地方创建一个heap dump,你可以在你的代码中调用dumpHprofData函数。

 

但是android的HPROF文件和java的HPROF文件略有不同,主要是因为android有多的分配是在Zygote进程进行的。我们需要将android HPROF文件转换成J2SE HPROF文件格式。实际上现在的eclipse都已经帮我们集成了这样的转换工作。如果你的没有自动转换,你可以使用<sdk>/tools/文件夹下面的hprof-conv工具来转换这个文件,例如:

 

hprof-conv heap-original.hprof heap-converted.hprof

 

我们现在可以使用MAT(Eclipse Memory Analyzer Tool)来分析这个文件了。

在分析的时候,我们需要关注这些问题:

 

1.       长时间存在的对Activity,Context,View,Drawable和其他对象的引用。

2.       非静态的内部类(比如runnable,这个会持有Activitu的实例)

3.       没有必要的一直持有某个对象

 

参考

https://developer.android.com/tools/debugging/debugging-memory.html

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值