Android内存使用情况分析

Android系统的内存由几个不同的内存池中的几个不同的分配器管理。
目录:

  1. 系统内存
  2. 进程内存
    2.1 procrank
    2.2 smem tool
  3. Dalvik Heap
  4. 调试Android应用内存占用情况
    4.1 如何调试native进程内存分配情况
    4.2 libc.debug.malloc

系统内存

通过查看 /proc/meminfo,可以检查机器 上的内存视图。
如果使用DDMS,则可以查看机器,系统和不同执行进程使用的内存摘要。单击SysInfo选项卡,然后在窗格左上角的框中选择“Memory Usage”。

image.png

请注意,您可以通过将鼠标悬停在特定的饼图切片上来获取每个过程的数字。 数字以K和百分比显示。

进程内存

您可以通过检查/proc/ / status来查看单个进程的内存使用情况

有关内存使用的详细信息

  • /proc//statm
  • /proc//maps
  • /proc//smaps
    'top'命令将显示VSS和RSS。另请参阅上面的ddms信息。

procrank

procrank将向您显示进程内存利用率的快速摘要。 默认情况下,它显示Vss,Rss,Pss和Uss,并按Vss排序。 但是,您可以控制排序顺序。
procrank源包含在system/extras/procrank中,二进制文件位于android设备上的/system/ xbin中。

  • Vss = virtual set size--虚拟集大小
  • Rss = resident set size--常驻内存大小
  • Pss = proportional set size--比例集大小
  • Uss = unique set size--独占集大小
    通常,您要观看的两个数字是Pss和Uss(Vss和Rss通常毫无价值,因为它们不能准确反映进程对与其他进程共享的页面的使用情况。)对整体内存负载的影响。
  • Uss是进程独有的页面集。 这是当前终止应用程序时将释放的内存量。
  • Pss是与其他进程共享的内存量,其计算方式是在共享它的进程之间平均分配额度。 这是在进程终止时不会释放的内存,但表示此进程“贡献”的数量
    您还可以使用procrank查看每个进程的工作集大小,并重置工作集大小计数器。
    这是procrank的用法:
# procrank -h
Usage: procrank [ -W ] [ -v | -r | -p | -u | -h ]
    -v  Sort by VSS.
    -r  Sort by RSS.
    -p  Sort by PSS.
    -u  Sort by USS.
        (Default sort order is PSS.)
    -R  Reverse sort order (default is descending).
    -w  Display statistics for working set only.
    -W  Reset working set of all processes.
    -h  Display this help screen.

以下是一些示例输出:

# procrank
  PID      Vss      Rss      Pss      Uss  cmdline
 1217   36848K   35648K   17983K   13956K  system_server
 1276   32200K   32200K   14048K   10116K  android.process.acore
 1189   26920K   26920K    9293K    5500K  zygote
 1321   20328K   20328K    4743K    2344K  android.process.media
 1356   20360K   20360K    4621K    2148K  com.android.email
 1303   20184K   20184K    4381K    1724K  com.android.settings
 1271   19888K   19888K    4297K    1764K  com.android.inputmethod.latin
 1332   19560K   19560K    3993K    1620K  com.android.alarmclock
 1187    5068K    5068K    2119K    1476K  /system/bin/mediaserver
 1384     436K     436K     248K     236K  procrank
    1     212K     212K     200K     200K  /init
  753     572K     572K     171K     136K  /system/bin/rild
  748     340K     340K     163K     152K  /system/bin/sh
  751     388K     388K     156K     140K  /system/bin/vold
 1215     148K     148K     136K     136K  /sbin/adbd
  757     352K     352K     117K      92K  /system/bin/dbus-daemon
  760     404K     404K     104K      80K  /system/bin/keystore
  759     312K     312K     102K      88K  /system/bin/installd
  749     288K     288K      96K      84K  /system/bin/servicemanager
  752     244K     244K      71K      60K  /system/bin/debuggerd

在此示例中,它显示本机守护程序和普通程序比基于Dalvik的服务和程序小一个数量级。 此外,即使是最小的Dalvik程序也需要大约1.5兆(Uss)才能运行。

smem tool

您可以通过smem查看非常详细的每个进程或系统范围的内存信息。安卓smem用法

Dalvik Heap

Dalvik堆由zygote预加载类和数据(从Android 2.2版开始加载超过1900个类)。当zygote分支启动Android应用程序时,新应用程序将获得此堆的写入时拷贝映射,这有助于减少内存和应用程序启动时间。
像许多其他语言的虚拟机一样,Dalvik在堆上进行垃圾收集。 每个VM进程中似乎都有一个单独的线程(称为HeapWorker),用于执行垃圾回收操作。
Dan Borstein谈到堆共享:
它在Android中用于分摊与所有活动VM进程中的公共库类相关联的大量有效只读数据(技术上可写但很少实际编写)的RAM占用空间。 系统在启动时预加载1000多个类,每个类至少消耗一小堆自身,包括经常指向其他对象的宿。 由预加载过程创建的堆与每个生成的VM进程共享写入时拷贝(但实际上并没有写得太多)。 这为每个进程节省了数百KB的"脏"的不可分页RAM,并且还有助于加速进程启动。
请参阅Dianne Hackborn的精彩文章调试Android应用程序内存使用情况

如何调试native进程内存分配情况

setprop dalvik.vm.checkjni true
setprop libc.debug.malloc 10   
setprop setprop dalvik.vm.jniopts forcecopy
start
stop

libc.debug.malloc

系统中的C库(仿生)支持在系统运行时使用malloc代码的不同调试版本的能力。
如果系统属性libc.debug.malloc的值不是0,那么在实例化进程时,C库将使用函数为该进程分配和释放内存。
(请注意,还有其他方法可以使用调试共享库malloc代码。也就是说,如果您在模拟器中运行,并且系统属性ro.kernel.memcheck的值不是'0', 然后你得到20的调试级别。注意,调试级别20只能在模拟器中使用。)
默认情况下,使用标准的malloc / free / calloc / realloc / memalign例程。 通过设置libc.debug.malloc,可以使用不同的例程来检查某些类型的内存错误(例如泄漏和溢出)。 这是通过使用这些不同的例程加载单独的共享库(.so)来完成的。
共享库的名称为:/system/lib/libc_malloc_debug_leak.so和/system/lib/libc_malloc_debug_qemu.so
(通过查看 /bionic/libc/bionic/malloc_debug_common.c获得信息)

libc.debug.malloc(调试级别值)支持的值为:

  • 1 - 执行泄漏检测
  • 5 - 填充分配的内存以检测溢出
  • 10 - 填充内存并添加标记以检测溢出
  • 20 - 为模拟器使用特殊的检测malloc / free例程
    但我不确定这些共享库是否在生产设备中提供。

你可能感兴趣的:(Android内存使用情况分析)