监控 android 内存使用方法 【转】

http://www.cnblogs.com/zdwillie/p/3287150.html

Native Heap分析和优化

android的DDMS可以帮助查看c++ native heap的使用,但需要一定的配置,而且必须是root的手机。

  1. 在~/.android/ddms.cfg增加"native=true"。这样子ddms才会有native heap的tab。
  2. 指向下面adb命令打开malloc的debug模式
    adb root
    adb shell setprop libc.debug.malloc 1
    adb shell stop
    adb shell start
  3. 打开standalone的DDMS(不是eclipse中那个,是独立的应用程序,sdk目录下有),然后在native heap这个tab下,可以查看native heap的分配情况。

      在很多手机上,即使执行了这些命令,还是看不到结果。原因是很多手机上并没有安装debug版本的malloc库(包括libc_malloc_debug_leak.so 和 libc_malloc_debug_qemu.so)。这篇经常被引用的文章介绍了一种方法。是从供大家刷机用的CyanogenMod image中提取这两个文件,然后拷贝到自己的机器上。可以参考那片文章的具体步骤。

      下面的问题是只能看到地址而不知道文件名和行号。至少有下面一些办法

    1. 使用ndk中的arm-linux-androideabi-gdb(android ndk的gdb)来打开.so文件。这里的.so不能使apk中使用的,因为那个已经把symbol给strip了。而应该使用 ***\obj\local\armeabi\***.so,这个是带着symbol的。
      然后可以在gdb中使用info symbol 0x000xxxxx来定位到地址对应的函数名。这里的0x000xxxxx是ddms中地址把前三位变成0。因为gdb .so中使用.so的静态地址,而ddms中的地址经过动态链接,是内存的虚拟地址。但动态链接并不改变地址的后五位,所以这里后五位保持不变,前三位变成0,从而转换为so的静态地址。
      然后用info line xxx.cpp:xxx来定位具体行。
      这个方法比较繁琐,因为当时自己没找到好办法,就这么用的。
    2. 用ndk的arm-linux-androideabi-addr2line。后面跟so和0x000xxxxx。跟gdb差不多,会简单一些。
    3. 有人说设置PATH加上包含addr2line的目录,然后再设置ANDROID_PRODUCT_OUT可以在ddms中直接显示函数名和行号,但没有试过。

 

 

一、 手机端准备工作

1、 安装库文件  

 

    所有的  native  内存分配函数  ( malloc  calloc , etc.)  都在  Android  libc   库中。为了跟踪堆内存的分配,需要使用这个库的特别版本,可以将每次内存开销记录下来。   这些特殊版本的   libc  ( libc_malloc_debug_leak.so  and  libc_malloc_debug_qemu.so  可以在手机中的/system/lib 下查看是否有这两个库  只包含在eng或者user-debug版的 Android中。 如果手机是这两种系统之一,可以跳过下一步。

 

    ①下载最接近你手机模型和 Android系统版本( 2.3 、 4.0 等)的 CyanogenMod ROM  。如果没有恰好是你手机的对应版本,那么选择处理器相同的  ( 比如 Tegra2)   Android系统版本(例如 2.3 )都相同的 rom. 。然后从 system/lib   文件夹   抽出 libc_malloc_debug_leak.so    libc_malloc_debug_qemu.so 

 

 

    ②以中兴 U880 手机为例,手机本身是移动定制的 Android2.2 系统, CyanogenMod  官网上恰有中兴的 rom,但是系统版本为 2.3.7 ,并且手机需要 root 权限,所以使用 U880 刷机工具,刷U880_2.3.7 root 版 rom 。

 

 

2、 替换库

 

 

①从 CM 版 rom 中 /system/lib 文件夹中抽出   libc_malloc_debug_leak.so  和 libc_malloc_debug_qemu.so

 

 

②把 libc_malloc_debug_leak.so  和  libc_malloc_debug_qemu.so  通过 USB拷到  SDCARD卡根目录下。

 

 

③手机中安装 BusyBox  以便使用 cp  命令复制文件。

 

 

       ④PC端命令行中执行

 

命令行代码  收藏代码
  1. adb shell  
  2.   
  3. su  
  4.   
  5. mount   

 

 

    不同手机返回的值不同,如下两例

 

     LG G2x:

     ...

     /dev/block/mmcblk0p1 /system ext3 ro,noatime,errors=continue,data=ordered 0 0

     ...

 

 

    中兴 U880 :

    ...

    /dev/block/ mtdblock11  /system  yaffs2  ro,relatime,barrier=1,data=ordered 0 0

    ...

 

第一部手机将  /dev/block/mmcblk0p1  作为设备,  ext3  作为文件系统类型。

第二部手机将 /dev/block/ mtdblock11  作为设备, yaffs2  作为文件系统类型。

 

 

    ⑤使用上面得到的设备名,和文件系统类型,重新挂载系统分区为读写格式。如下所示:

    LG G2x:

命令行代码  收藏代码
  1. mount -o remount,rw -t ext3 /dev/block/mmcblk0p1 /system  

 

    中兴 U880 :

 

命令行代码  收藏代码
  1. mount -o remount,rw -t  yaffs2  /dev/block/ mtdblock11  /system    

 

  ⑥ 把两个库文件从S DCARD 拷到 /system/lib  目录: 

 

命令行代码  收藏代码
  1. cp /sdcard/libc_malloc_debug_leak.so /system/lib/libc_malloc_debug_leak.so  
  2.   
  3. cp /sdcard/libc_malloc_debug_qemu.so /system/lib/libc_malloc_debug_qemu.so   

 

 

  ⑦ 设置权限

 

 

命令行代码  收藏代码
  1. chmod 0644 /system/lib/libc_malloc_debug_leak.so  
  2.   
  3. chmod 0644 /system/lib/libc_malloc_debug_qemu.so   

 

 

3、 配置

      替换完新的库文件后,告知系统使用新的库分配内存。

 ②命令行中执行

命令行代码  收藏代码
  1. adb shell  
  2.   
  3. su  
  4.   
  5. setprop libc.debug.malloc 1  

 

    支持的参数:

 

 

1  - perform leak detection

5  - fill allocated memory to detect overruns

10 - fill memory and add sentinels to detect overruns

20 - use special instrumented malloc/free routines for the emulator

 

 

      重启框架 ,命令行中继续执行

 

命令行代码  收藏代码
  1. stop  
  2. start  

 

     如果命令成功,设备将在 1、 2 秒后重启, 注意并不是完全重启。 

 

    ④ 检查配置

     输入:

      

命令行代码  收藏代码
  1. getprop  

 

 

 

   将会得到很多信息,其中包括:

    ...

    [libc.debug.malloc]: [1]

    ...

 

    说明配置成功

 

 

 

 

 

 

 

 

 

posted @ 2013-12-20 20:26  曙光中睡懒觉  阅读(1625)  评论(0)    收藏  举报