Android 获取内存使用状况的总结

1.Java代码获取

Yes, you can get memory info programmatically and decide whether to do memory intensive work.

Get VM Heap Size by calling:

Runtime.getRuntime().totalMemory();

Get Allocated VM Memory by calling:

Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();

Get VM Heap Size Limit by calling:

Runtime.getRuntime().maxMemory()

Get Native Allocated Memory by calling:

Debug.getNativeHeapAllocatedSize();
2.sysdump命令 ( http://stackoverflow.com/questions/2298208/how-to-discover-memory-usage-of-my-application-in-android#2299813)

Using adb, there is a lot of information you can get about the memory use of a running system. A common one is the command "adb shell dumpsys meminfo" which will spit out a bunch of information about the memory use of each Java process, containing the above info as well as a variety of other things. You can also tack on the name or pid of a single process to see, for example "adb shell dumpsys meminfo system" give me the system process:

** MEMINFO in pid 890 [system] **
                    native   dalvik    other    total
            size:    10940     7047      N/A    17987
       allocated:     8943     5516      N/A    14459
            free:      336     1531      N/A     1867
           (Pss):     4585     9282    11916    25783
  (shared dirty):     2184     3596      916     6696
    (priv dirty):     4504     5956     7456    17916

 Objects
           Views:      149        ViewRoots:        4
     AppContexts:       13       Activities:        0
          Assets:        4    AssetManagers:        4
   Local Binders:      141    Proxy Binders:      158
Death Recipients:       49
 OpenSSL Sockets:        0

 SQL
            heap:      205          dbFiles:        0
       numPagers:        0   inactivePageKB:        0
    activePageKB:        0

The top section is the main one, where "size" is the total size in address space of a particular heap, "allocated" is the kb of actual allocations that heap thinks it has, "free" is the remaining kb free the heap has for additional allocations, and "pss" and "priv dirty" are the same as discussed before specific to pages associated with each of the heaps.

If you just want to look at memory usage across all processes, you can use the command "adb shell procrank". Output of this on the same system looks like:

  PID      Vss      Rss      Pss      Uss  cmdline
  890   84456K   48668K   25850K   21284K  system_server
 1231   50748K   39088K   17587K   13792K  com.android.launcher2
  947   34488K   28528K   10834K    9308K  com.android.wallpaper
  987   26964K   26956K    8751K    7308K  com.google.process.gapps
  954   24300K   24296K    6249K    4824K  com.android.phone
  948   23020K   23016K    5864K    4748K  com.android.inputmethod.latin
  888   25728K   25724K    5774K    3668K  zygote
  977   24100K   24096K    5667K    4340K  android.process.acore
...
   59     336K     332K      99K      92K  /system/bin/installd
   60     396K     392K      93K      84K  /system/bin/keystore
   51     280K     276K      74K      68K  /system/bin/servicemanager
   54     256K     252K      69K      64K  /system/bin/debuggerd

Here the Vss and Rss columns are basically noise (these are the straight-forward address space and RAM usage of a process, where if you add up the RAM usage across processes you get an ridiculously large number).

Pss is as we've seen before, and Uss is Priv Dirty.



dumpsys命令可以显示手机中所有应用程序的信息,并且也会给出现在手机的状态。

直接执行adb shell dumpsys会显示以下所有信息。

dumpsys的参数可以跟以上信息的名字。例如:

adb shell dumpsys activity 显示activity相关的信息

adb shell dumpsys statusbar 显示状态栏相关的信息

adb shell dumpsys meminfo $package_name or $pid 使用程序的包名或者进程id显示内存信息

可以通过这个命令实现很多有用的小应用,比如内存信息相关的,状态栏的通知都是哪个应用谈出来的等等。

我通过这个命令写了一个小应用”找出状态栏广告的主人“。普通通知很容易辨认是哪个应用的,广告就不好辨认了。

其实应用就相当于一条shell命令:

adb shell dumpsys statusbar | grep notification=Notification

这条命令可以找出状态栏通知的包名,进而找到是哪个应用。

这个点子来自:http://www.maxhis.info/archives/731

只是我把它做成了手机上应用。需要注意的是这个应用需要root权限才能执行!

还有很多可以做的,找住对你有用的吧!

3.使用ddms查看


在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 the tools/ 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的内容(有一点复杂):

  1. 第一个HPROF 文件(using File > Open Heap Dump ).
  2. 打开 Histogram view.
  3. 在Navigation History view里 (如果看不到就从Window > Navigation History找 ), 右击histogram 然后选择Add to Compare Basket .
  4. 打开第二个HPROF 文件然后重做步骤2和3.
  5. 切换到Compare Basket view, 然后点击Compare the Results (视图右上角的红色"!"图标)。

总结

这本篇文章里面,我展示了Allocation Tracker和heap dumps是如何给你一种对程序内存使用的感性认识。我也展示了Eclipse Memory Analyzer(MAT)可以帮助追逐我们程序里面的内存泄露问题。MAT是一个强大的工具,我也仅仅触碰了一些皮毛,如果你想学习更多内容,我建议读 一些下面的文章:


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值