Android 内存分析

转自:http://blog.csdn.net/heng615975867/article/details/51259410

一、概述

1.1 内存指标概念

Item 全称 含义 等价
USS Unique Set Size 物理内存 进程独占的内存
PSS Proportional Set Size 物理内存 PSS= USS+ 按比例包含共享库
RSS Resident Set Size 物理内存 RSS= USS+ 包含共享库
VSS Virtual Set Size 虚拟内存 VSS= RSS+ 未分配实际物理内存


故内存的大小关系:VSS >= RSS >= PSS >= USS


1.2 内存分析命令


常用的内存调优分析命令:


  1. dumpsys meminfo

  2. procrank

  3. cat /proc/meminfo

  4. free

  5. showmap

  6. vmstat


二 命令说明


1. dumpsys meminfo


dumpsys meminfo命令的输出结果分以下4部分


序列 划分类型 排序 解释
1 process PSS 以进程的PSS从大到小依次排序显示,每行显示一个进程;
2 OOM adj PSS Native/System/Persistent/Foreground/Visible/Perceptible/A Services/Home/B Services/Cached,分别显示每类的进程情况
3 category PSS 以Dalvik/Native/.art mmap/.dex map等划分的各类进程的总PSS情况
4 total 总内存、剩余内存、可用内存、其他内存


命令内容:


Total PSS by process: //以process来划分

   167128 kB: com.Android.systemui (pid 4395)

   124527 kB: system (pid 1192)

    44213 kB: com.android.settings (pid 29256 / activities)

    41822 kB: surfaceflinger (pid 391)

    ...

 

Total PSS by OOM adjustment: //以oom来划分,会详细列举所有的类别的进程,此处省略.

   183683 kB: Native

        42024 kB: surfaceflinger (pid 388)

        16740 kB: mediaserver (pid 471)

        16040 kB: zygote (pid 494)

        ...

   124527 kB: System

   344259 kB: Persistent

    69719 kB: Foreground

    49026 kB: Visible

    34005 kB: Perceptible

     7880 kB: A Services

    58689 kB: Home

    98352 kB: B Services

    94888 kB: Cached


Total PSS by category:  // 以category划分

   309449 kB: Dalvik

   230330 kB: Native

   145344 kB: EGL mtrack

   117797 kB: .so mmap  

    54389 kB: .art mmap  

    44886 kB: .dex mmap

    32428 kB: Dalvik Other

    31083 kB: .oat mmap

    29456 kB: Stack

    21782 kB: Gfx dev

    21733 kB: Unknown

    12695 kB: .apk mmap  

     9367 kB: Other mmap

     2169 kB: .ttf mmap

     2062 kB: Other dev

       38 kB: .jar mmap

       12 kB: Ashmem

        8 kB: Cursor

        0 kB: GL mtrack

        0 kB: Other mtrack

 

//整体情况

Total RAM: 2857032 kB (status moderate)

Free RAM: 1439488 kB (94888 cached pss + 344620 cached kernel + 999980 free)

Used RAM: 1280552 kB (970140 used pss + 310412 kernel)

Lost RAM: 136992 kB

     ZRAM: 4 kB physical used for 0 kB in swap (524284 kB total swap)

   Tuning: 256 (large 512), oom 525000 kB, restore limit 175000 kB (high-end-gfx)


另外,可只输出某个pid或package的进程信息:


dumpsys meminfo  // 输出指定pid的某一进程

dumpsys meminfo --package  // 输出指定包名的进程,可能包含多个进程

例如 要查看 com.android.systemui 的内存使用情况

adb shell dumpsys meminfo com.android.systemui

** MEMINFO in pid 1179 [com.android.systemui] **
                   Pss  Private  Private  Swapped     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap     7207     7184        0      260     8192     8043       92
  Dalvik Heap    69196    69144        0     1028    72248    69354     2894
 Dalvik Other     2587     2504        0     1012                           
        Stack      156      156        0       16                           
       Ashmem        2        0        0        0                           
    Other dev        5        0        4        0                           
     .so mmap      920      204       20     2688                           
    .apk mmap     1516        0        4        0                           
    .ttf mmap        4        0        0        0                           
    .dex mmap     1272       68      652      136                           
   Other mmap       37        4       28        0                           
      Unknown      108      108        0        8                           
        TOTAL    83010    79372      708     5148    80440    77397     2986
 
 Objects
               Views:      414         ViewRootImpl:        1
         AppContexts:        9           Activities:        0
              Assets:        6        AssetManagers:        6
       Local Binders:       76        Proxy Binders:       48
    Death Recipients:        3
     OpenSSL Sockets:        0
 SQL
         MEMORY_USED:        0
  PAGECACHE_OVERFLOW:        0          MALLOC_SIZE:        0


可以查看Native Heap 和 Davilik Heap 使用情况


查看GC log

先查看systemui 进程id

adb shell ps | grep systemui

u0_a64    910   195   939612 75312 ffffffff 400aa560 S com.android.systemui

查看 log

adb logcat -v time | grep "910): GC_"


01-01 01:20:22.040 D/dalvikvm(  910): GC_EXPLICIT freed 865K (12243), 51% free 29409K/59320K, paused 6ms+7ms, total 56ms
01-01 01:20:26.497 D/dalvikvm(  910): GC_FOR_ALLOC freed 316K (4580), 44% free 33467K/59320K, paused 49ms, total 49ms

adb logcat -v time -s dalvikvm-heap
01-01 01:21:26.511 I/dalvikvm-heap(  910): Grow heap (frag case) to 64.409MB for 16588816-byte allocatio


1、GC_FOR_ALLOC:发生在堆被占满不能进行内存分配时,在分配新对象之前必须进行内存回收。

2、GC_CONCURRENT:发生在(可能是部分的)垃圾可供回收时,通常有很多对象可以回收。

3、GC_EXPLICIT:显式调用System.gc()产生的垃圾收集。


freed 865K  表示 释放865k 内存, 51% free 29409K/59320K 表示heapsize 是 59M 已用29M 有51%的 free


2. procrank


功能: 获取所有进程的内存使用的排行榜,排行是以Pss的大小而排序。procrank命令比dumpsys meminfo命令,能输出更详细的VSS/RSS/PSS/USS内存指标。


最后一行输出下面6个指标:


total free buffers cached shmem slab


执行结果:


root@Phone:/#procrank

  PID       Vss      Rss      Pss      Uss  cmdline

4395  2270020K  202312K  136099K  121964K  com.android.systemui

1192  2280404K  147048K  89883K  84144K  system_server

29256  2145676K  97880K  44328K  40676K  com.android.settings

  501  1458332K  61876K  23609K    9736K  zygote

4239  2105784K  68056K  21665K  19592K  com.android.phone

  479  164392K  24068K  17970K  15364K  /system/bin/mediaserver

  391  200892K  27272K  15930K  11664K  /system/bin/surfaceflinger

...

RAM:2857032Ktotal,998088Kfree,78060Kbuffers,459780Kcached,312Kshmem,92392Kslab



一般观察Uss来反映一个Process的内存使用情况,Uss 的大小代表了只属于本进程正在使
用的内存大小,这些内存在此Process被杀掉之后,会被完整的回收掉,
Vss和Rss对查看某一Process自身内存状况没有什么价值,因为他们包含了共享库的内存使
用,而往往共享库的资源占用比重是很大的,这样就稀释了对Process自身创建内存波动。
而Pss是按照比例将共享内存分割,某一Process对共享内存的占用情况。
procrank 的代码在 /system/extras/procrank,,在模拟器或者设备上的运行文件位/system/xbin
在adb shell之后,我们运行procrank

adb shell procrank

我们还可以使用脚本配合procrank跟踪内存变化
使用procrank来跟踪某进程的使用哪个情况我们常常借助与脚本。这样就可以查看某一段时间
的内存变化。
如创建一个文件:trackmem.sh chmod 775 trackmem.sh
内容如下:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #!/bin/bash  
  2. while truedo   
  3. adb shell procrank | grep "com.baidu.BaiduReader"  
  4. sleep 1   
  5. done  

运行该脚本:
./trackmem.sh
这个脚本的用途是每1秒钟让系统输出一次BaiduReader的内存使用状况



3. cat /proc/meminfo


功能:能否查看更加详细的内存信息


指令: cat /proc/meminfo


输出结果如下(结果内存值不带小数点,此处添加小数点的目的是为了便于比对大小):


root@phone:/ # cat /proc/meminfo

MemTotal:        2857.032 kB  //RAM可用的总大小 (即物理总内存减去系统预留和内核二进制代码大小)

MemFree:         1020.708 kB  //RAM未使用的大小

Buffers:           75.104 kB  //用于文件缓冲

Cached:           448.244 kB  //用于高速缓存

SwapCached:             0 kB  //用于swap缓存

 

Active:           832.900 kB  //活跃使用状态,记录最近使用过的内存,通常不回收用于其它目的

Inactive:         391.128 kB  //非活跃使用状态,记录最近并没有使用过的内存,能够被回收用于其他目的

Active(anon):     700.744 kB  //Active = Active(anon) + Active(file)

Inactive(anon):       228 kB  //Inactive = Inactive(anon) + Inactive(file)

Active(file):     132.156 kB

Inactive(file):   390.900 kB

 

Unevictable:            0 kB

Mlocked:                0 kB

 

SwapTotal:        524.284 kB  //swap总大小

SwapFree:         524.284 kB  //swap可用大小

Dirty:                  0 kB  //等待往磁盘回写的大小

Writeback:              0 kB  //正在往磁盘回写的大小

 

AnonPages:        700.700 kB  

Mapped:           187.096 kB  //通过mmap()分配的内存,用于map设备、文件或者库

Shmem:               .312 kB

 

Slab:              91.276 kB  //kernel数据结构的缓存大小,Slab=SReclaimable+SUnreclaim

SReclaimable:      32.484 kB  //可回收的slab的大小

SUnreclaim:        58.792 kB  //不可回收slab的大小

 

KernelStack:       25.024 kB

PageTables:        23.752 kB  //以最低的页表级

NFS_Unstable:           0 kB  //不稳定页表的大小

Bounce:                 0 kB

WritebackTmp:           0 kB

CommitLimit:     1952.800 kB

Committed_AS:   82204.348 kB   //评估完成的工作量,代表最糟糕case下的值,该值也包含swap内存

 

VmallocTotal:  251658.176 kB  //总分配的虚拟地址空间

VmallocUsed:      166.648 kB  //已使用的虚拟地址空间

VmallocChunk:  251398.700 kB  //虚拟地址空间可用的最大连续内存块


对于cache和buffer也是系统可以使用的内存。所以系统总的可用内存为 MemFree+Buffers+Cached


4.free


主功能:查看可用内存,缺省单位KB。该命令比较简单、轻量,专注于查看剩余内存情况。数据来源于/proc/meminfo。


输出结果:


root@phone:/proc/sys/vm # free

             total         used         free       shared      buffers

Mem:       2857032      1836040      1020992            0        75104

-/+ buffers:            1760936      1096096

Swap:       524284            0       524284



  • 对于Mem行,存在的公式关系: total = used + free;

  • 对于-/+ buffers行: 1760936 = 1836040 – 75104(buffers); 1096096 = 1020992 + 75104(buffers);



5. showmap


主功能:用于查看虚拟地址区域的内存情况


用法:  showmap -a [pid]  


该命令的输出每一行代表一个虚拟地址区域(vm area)


root@phone:/ # showmap -a 10901

   start    end      virtual                   shared   shared  private  private

    addr     addr     size      RSS      PSS    clean    dirty    clean    dirty object

-------- -------- -------- -------- -------- -------- -------- -------- -------- ------------------------------

f3b87000 f3d85000     2040        4        4        0        0        4        0 /dev/binder


  • start addr和end addr:分别代表进程空间的起止虚拟地址;

  • virtual size/ RSS /PSS这些前面介绍过;

  • shared clean:代表多个进程的虚拟地址可指向这块物理空间,即有多少个进程共享这个库;

  • shared: 共享数据

  • private: 该进程私有数据

  • clean: 干净数据,是指该内存数据与disk数据一致,当内存紧张时,可直接释放内存,不需要回写到disk

  • dirty: 脏数据,与disk数据不一致,需要先回写到disk,才能被释放。


功能与cat /proc/[pid]/maps基本一致。


6. vmstat


主功能:不仅可以查看内存情况,还可以查看进程运行队列、系统切换、CPU时间占比等情况,另外该指令还是周期性地动态输出。


用法:


Usage: vmstat [ -n iterations ] [ -d delay ] [ -r header_repeat ]

    -n iterations     数据循环输出的次数

    -d delay          两次数据间的延迟时长(单位:S)

    -r header_repeat  循环多少次,再输出一次头信息行


输入结果:


root@phone:/ # vmstat

procs  memory                       system          cpu

r  b   free  mapped   anon   slab    in   cs  flt  us ni sy id wa ir

2  0  663436 232836 915192 113960   196  274    0   8  0  2 99  0  0

0  0  663444 232836 915108 113960   180  260    0   7  0  3 99  0  0

0  0  663476 232836 915216 113960   154  224    0   2  0  5 99  0  0

1  0  663132 232836 915304 113960   179  259    0  11  0  3 99  0  0

2  0  663124 232836 915096 113960   110  175    0   4  0  3 99  0  0


参数列总共15个参数,分为4大类:


  • procs(进程)

    • r: Running队列中进程数量

    • b: IO wait的进程数量

  • memory(内存)

    • free: 可用内存大小

    • mapped:mmap映射的内存大小

    • anon: 匿名内存大小

    • slab: slab的内存大小

  • system(系统)

    • in: 每秒的中断次数(包括时钟中断)

    • cs: 每秒上下文切换的次数

  • cpu(处理器)

    • us: user time

    • ni: nice time

    • sy: system time

    • id: idle time

    • wa: iowait time

    • ir: interrupt time


7. getprop

主要功能:查看当前手机HEAP size 设定


adb shell getprop | grep heap

[dalvik.vm.heapgrowthlimit]: [192m]
[dalvik.vm.heapsize]: [512m]



8. CashHandler

利用CashHandler 自动dump hprof 文件,为了便于在OOM发生的时候 能够Dump Hprof 文件。 提供分析。可以设置全局的CashHandler  并判断是否OOM ,如果是OOM 则利用

Debug类dump hprof 文件:

dumpHprofData(String fileName)

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. private static final String OOM = "java.lang.OutOfMemoryError";  
  2. if (isOOM(arg1)) {  
  3.     SimpleDateFormat sDateFormat =  
  4.             new SimpleDateFormat("MM_dd_hh_mm_ss");  
  5.     String date = sDateFormat.format(new Date());  
  6.     File dumpfile = new File(logdir + File.separator + "oom" + date  
  7.             + ".hprof");  
  8.     Debug.dumpHprofData(dumpfile.getAbsolutePath());  
  9. }  

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public static boolean isOOM(Throwable throwable){  
  2.     if(OOM.equalsIgnoreCase(throwable.getClass().getName())){  
  3.         return true;  
  4.     }else{  
  5.         Throwable cause = throwable.getCause();  
  6.         if(cause != null){  
  7.             return isOOM(cause);  
  8.         }  
  9.         return false;  
  10.     }  
  11. }  




小结


  1. dumpsys meminfo适用场景: 查看进程的oom adj,或者dalvik/native等区域内存情况,或者某个进程或apk的内存情况,功能非常强大;

  2. procrank适用场景: 查看进程的VSS/RSS/PSS/USS各个内存指标;

  3. cat /proc/meminfo适用场景: 查看系统的详尽内存信息,包含内核情况;

  4. free适用场景: 只查看系统的可用内存;

  5. showmap适用场景: 查看进程的虚拟地址空间的内存分配情况;

  6. vmstat适用场景: 周期性地打印出进程运行队列、系统切换、CPU时间占比等情况;

  7. getprop:查看当前手机HEAP size 设定



一、概述

1.1 内存指标概念

Item 全称 含义 等价
USS Unique Set Size 物理内存 进程独占的内存
PSS Proportional Set Size 物理内存 PSS= USS+ 按比例包含共享库
RSS Resident Set Size 物理内存 RSS= USS+ 包含共享库
VSS Virtual Set Size 虚拟内存 VSS= RSS+ 未分配实际物理内存


故内存的大小关系:VSS >= RSS >= PSS >= USS


1.2 内存分析命令


常用的内存调优分析命令:


  1. dumpsys meminfo

  2. procrank

  3. cat /proc/meminfo

  4. free

  5. showmap

  6. vmstat


二 命令说明


1. dumpsys meminfo


dumpsys meminfo命令的输出结果分以下4部分


序列 划分类型 排序 解释
1 process PSS 以进程的PSS从大到小依次排序显示,每行显示一个进程;
2 OOM adj PSS Native/System/Persistent/Foreground/Visible/Perceptible/A Services/Home/B Services/Cached,分别显示每类的进程情况
3 category PSS 以Dalvik/Native/.art mmap/.dex map等划分的各类进程的总PSS情况
4 total 总内存、剩余内存、可用内存、其他内存


命令内容:


Total PSS by process: //以process来划分

   167128 kB: com.Android.systemui (pid 4395)

   124527 kB: system (pid 1192)

    44213 kB: com.android.settings (pid 29256 / activities)

    41822 kB: surfaceflinger (pid 391)

    ...

 

Total PSS by OOM adjustment: //以oom来划分,会详细列举所有的类别的进程,此处省略.

   183683 kB: Native

        42024 kB: surfaceflinger (pid 388)

        16740 kB: mediaserver (pid 471)

        16040 kB: zygote (pid 494)

        ...

   124527 kB: System

   344259 kB: Persistent

    69719 kB: Foreground

    49026 kB: Visible

    34005 kB: Perceptible

     7880 kB: A Services

    58689 kB: Home

    98352 kB: B Services

    94888 kB: Cached


Total PSS by category:  // 以category划分

   309449 kB: Dalvik

   230330 kB: Native

   145344 kB: EGL mtrack

   117797 kB: .so mmap  

    54389 kB: .art mmap  

    44886 kB: .dex mmap

    32428 kB: Dalvik Other

    31083 kB: .oat mmap

    29456 kB: Stack

    21782 kB: Gfx dev

    21733 kB: Unknown

    12695 kB: .apk mmap  

     9367 kB: Other mmap

     2169 kB: .ttf mmap

     2062 kB: Other dev

       38 kB: .jar mmap

       12 kB: Ashmem

        8 kB: Cursor

        0 kB: GL mtrack

        0 kB: Other mtrack

 

//整体情况

Total RAM: 2857032 kB (status moderate)

Free RAM: 1439488 kB (94888 cached pss + 344620 cached kernel + 999980 free)

Used RAM: 1280552 kB (970140 used pss + 310412 kernel)

Lost RAM: 136992 kB

     ZRAM: 4 kB physical used for 0 kB in swap (524284 kB total swap)

   Tuning: 256 (large 512), oom 525000 kB, restore limit 175000 kB (high-end-gfx)


另外,可只输出某个pid或package的进程信息:


dumpsys meminfo  // 输出指定pid的某一进程

dumpsys meminfo --package  // 输出指定包名的进程,可能包含多个进程

例如 要查看 com.android.systemui 的内存使用情况

adb shell dumpsys meminfo com.android.systemui

** MEMINFO in pid 1179 [com.android.systemui] **
                   Pss  Private  Private  Swapped     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap     7207     7184        0      260     8192     8043       92
  Dalvik Heap    69196    69144        0     1028    72248    69354     2894
 Dalvik Other     2587     2504        0     1012                           
        Stack      156      156        0       16                           
       Ashmem        2        0        0        0                           
    Other dev        5        0        4        0                           
     .so mmap      920      204       20     2688                           
    .apk mmap     1516        0        4        0                           
    .ttf mmap        4        0        0        0                           
    .dex mmap     1272       68      652      136                           
   Other mmap       37        4       28        0                           
      Unknown      108      108        0        8                           
        TOTAL    83010    79372      708     5148    80440    77397     2986
 
 Objects
               Views:      414         ViewRootImpl:        1
         AppContexts:        9           Activities:        0
              Assets:        6        AssetManagers:        6
       Local Binders:       76        Proxy Binders:       48
    Death Recipients:        3
     OpenSSL Sockets:        0
 SQL
         MEMORY_USED:        0
  PAGECACHE_OVERFLOW:        0          MALLOC_SIZE:        0


可以查看Native Heap 和 Davilik Heap 使用情况


查看GC log

先查看systemui 进程id

adb shell ps | grep systemui

u0_a64    910   195   939612 75312 ffffffff 400aa560 S com.android.systemui

查看 log

adb logcat -v time | grep "910): GC_"


01-01 01:20:22.040 D/dalvikvm(  910): GC_EXPLICIT freed 865K (12243), 51% free 29409K/59320K, paused 6ms+7ms, total 56ms
01-01 01:20:26.497 D/dalvikvm(  910): GC_FOR_ALLOC freed 316K (4580), 44% free 33467K/59320K, paused 49ms, total 49ms

adb logcat -v time -s dalvikvm-heap
01-01 01:21:26.511 I/dalvikvm-heap(  910): Grow heap (frag case) to 64.409MB for 16588816-byte allocatio


1、GC_FOR_ALLOC:发生在堆被占满不能进行内存分配时,在分配新对象之前必须进行内存回收。

2、GC_CONCURRENT:发生在(可能是部分的)垃圾可供回收时,通常有很多对象可以回收。

3、GC_EXPLICIT:显式调用System.gc()产生的垃圾收集。


freed 865K  表示 释放865k 内存, 51% free 29409K/59320K 表示heapsize 是 59M 已用29M 有51%的 free


2. procrank


功能: 获取所有进程的内存使用的排行榜,排行是以Pss的大小而排序。procrank命令比dumpsys meminfo命令,能输出更详细的VSS/RSS/PSS/USS内存指标。


最后一行输出下面6个指标:


total free buffers cached shmem slab


执行结果:


root@Phone:/#procrank

  PID       Vss      Rss      Pss      Uss  cmdline

4395  2270020K  202312K  136099K  121964K  com.android.systemui

1192  2280404K  147048K  89883K  84144K  system_server

29256  2145676K  97880K  44328K  40676K  com.android.settings

  501  1458332K  61876K  23609K    9736K  zygote

4239  2105784K  68056K  21665K  19592K  com.android.phone

  479  164392K  24068K  17970K  15364K  /system/bin/mediaserver

  391  200892K  27272K  15930K  11664K  /system/bin/surfaceflinger

...

RAM:2857032Ktotal,998088Kfree,78060Kbuffers,459780Kcached,312Kshmem,92392Kslab



一般观察Uss来反映一个Process的内存使用情况,Uss 的大小代表了只属于本进程正在使
用的内存大小,这些内存在此Process被杀掉之后,会被完整的回收掉,
Vss和Rss对查看某一Process自身内存状况没有什么价值,因为他们包含了共享库的内存使
用,而往往共享库的资源占用比重是很大的,这样就稀释了对Process自身创建内存波动。
而Pss是按照比例将共享内存分割,某一Process对共享内存的占用情况。
procrank 的代码在 /system/extras/procrank,,在模拟器或者设备上的运行文件位/system/xbin
在adb shell之后,我们运行procrank

adb shell procrank

我们还可以使用脚本配合procrank跟踪内存变化
使用procrank来跟踪某进程的使用哪个情况我们常常借助与脚本。这样就可以查看某一段时间
的内存变化。
如创建一个文件:trackmem.sh chmod 775 trackmem.sh
内容如下:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #!/bin/bash  
  2. while truedo   
  3. adb shell procrank | grep "com.baidu.BaiduReader"  
  4. sleep 1   
  5. done  

运行该脚本:
./trackmem.sh
这个脚本的用途是每1秒钟让系统输出一次BaiduReader的内存使用状况



3. cat /proc/meminfo


功能:能否查看更加详细的内存信息


指令: cat /proc/meminfo


输出结果如下(结果内存值不带小数点,此处添加小数点的目的是为了便于比对大小):


root@phone:/ # cat /proc/meminfo

MemTotal:        2857.032 kB  //RAM可用的总大小 (即物理总内存减去系统预留和内核二进制代码大小)

MemFree:         1020.708 kB  //RAM未使用的大小

Buffers:           75.104 kB  //用于文件缓冲

Cached:           448.244 kB  //用于高速缓存

SwapCached:             0 kB  //用于swap缓存

 

Active:           832.900 kB  //活跃使用状态,记录最近使用过的内存,通常不回收用于其它目的

Inactive:         391.128 kB  //非活跃使用状态,记录最近并没有使用过的内存,能够被回收用于其他目的

Active(anon):     700.744 kB  //Active = Active(anon) + Active(file)

Inactive(anon):       228 kB  //Inactive = Inactive(anon) + Inactive(file)

Active(file):     132.156 kB

Inactive(file):   390.900 kB

 

Unevictable:            0 kB

Mlocked:                0 kB

 

SwapTotal:        524.284 kB  //swap总大小

SwapFree:         524.284 kB  //swap可用大小

Dirty:                  0 kB  //等待往磁盘回写的大小

Writeback:              0 kB  //正在往磁盘回写的大小

 

AnonPages:        700.700 kB  

Mapped:           187.096 kB  //通过mmap()分配的内存,用于map设备、文件或者库

Shmem:               .312 kB

 

Slab:              91.276 kB  //kernel数据结构的缓存大小,Slab=SReclaimable+SUnreclaim

SReclaimable:      32.484 kB  //可回收的slab的大小

SUnreclaim:        58.792 kB  //不可回收slab的大小

 

KernelStack:       25.024 kB

PageTables:        23.752 kB  //以最低的页表级

NFS_Unstable:           0 kB  //不稳定页表的大小

Bounce:                 0 kB

WritebackTmp:           0 kB

CommitLimit:     1952.800 kB

Committed_AS:   82204.348 kB   //评估完成的工作量,代表最糟糕case下的值,该值也包含swap内存

 

VmallocTotal:  251658.176 kB  //总分配的虚拟地址空间

VmallocUsed:      166.648 kB  //已使用的虚拟地址空间

VmallocChunk:  251398.700 kB  //虚拟地址空间可用的最大连续内存块


对于cache和buffer也是系统可以使用的内存。所以系统总的可用内存为 MemFree+Buffers+Cached


4.free


主功能:查看可用内存,缺省单位KB。该命令比较简单、轻量,专注于查看剩余内存情况。数据来源于/proc/meminfo。


输出结果:


root@phone:/proc/sys/vm # free

             total         used         free       shared      buffers

Mem:       2857032      1836040      1020992            0        75104

-/+ buffers:            1760936      1096096

Swap:       524284            0       524284



  • 对于Mem行,存在的公式关系: total = used + free;

  • 对于-/+ buffers行: 1760936 = 1836040 – 75104(buffers); 1096096 = 1020992 + 75104(buffers);



5. showmap


主功能:用于查看虚拟地址区域的内存情况


用法:  showmap -a [pid]  


该命令的输出每一行代表一个虚拟地址区域(vm area)


root@phone:/ # showmap -a 10901

   start    end      virtual                   shared   shared  private  private

    addr     addr     size      RSS      PSS    clean    dirty    clean    dirty object

-------- -------- -------- -------- -------- -------- -------- -------- -------- ------------------------------

f3b87000 f3d85000     2040        4        4        0        0        4        0 /dev/binder


  • start addr和end addr:分别代表进程空间的起止虚拟地址;

  • virtual size/ RSS /PSS这些前面介绍过;

  • shared clean:代表多个进程的虚拟地址可指向这块物理空间,即有多少个进程共享这个库;

  • shared: 共享数据

  • private: 该进程私有数据

  • clean: 干净数据,是指该内存数据与disk数据一致,当内存紧张时,可直接释放内存,不需要回写到disk

  • dirty: 脏数据,与disk数据不一致,需要先回写到disk,才能被释放。


功能与cat /proc/[pid]/maps基本一致。


6. vmstat


主功能:不仅可以查看内存情况,还可以查看进程运行队列、系统切换、CPU时间占比等情况,另外该指令还是周期性地动态输出。


用法:


Usage: vmstat [ -n iterations ] [ -d delay ] [ -r header_repeat ]

    -n iterations     数据循环输出的次数

    -d delay          两次数据间的延迟时长(单位:S)

    -r header_repeat  循环多少次,再输出一次头信息行


输入结果:


root@phone:/ # vmstat

procs  memory                       system          cpu

r  b   free  mapped   anon   slab    in   cs  flt  us ni sy id wa ir

2  0  663436 232836 915192 113960   196  274    0   8  0  2 99  0  0

0  0  663444 232836 915108 113960   180  260    0   7  0  3 99  0  0

0  0  663476 232836 915216 113960   154  224    0   2  0  5 99  0  0

1  0  663132 232836 915304 113960   179  259    0  11  0  3 99  0  0

2  0  663124 232836 915096 113960   110  175    0   4  0  3 99  0  0


参数列总共15个参数,分为4大类:


  • procs(进程)

    • r: Running队列中进程数量

    • b: IO wait的进程数量

  • memory(内存)

    • free: 可用内存大小

    • mapped:mmap映射的内存大小

    • anon: 匿名内存大小

    • slab: slab的内存大小

  • system(系统)

    • in: 每秒的中断次数(包括时钟中断)

    • cs: 每秒上下文切换的次数

  • cpu(处理器)

    • us: user time

    • ni: nice time

    • sy: system time

    • id: idle time

    • wa: iowait time

    • ir: interrupt time


7. getprop

主要功能:查看当前手机HEAP size 设定


adb shell getprop | grep heap

[dalvik.vm.heapgrowthlimit]: [192m]
[dalvik.vm.heapsize]: [512m]



8. CashHandler

利用CashHandler 自动dump hprof 文件,为了便于在OOM发生的时候 能够Dump Hprof 文件。 提供分析。可以设置全局的CashHandler  并判断是否OOM ,如果是OOM 则利用

Debug类dump hprof 文件:

dumpHprofData(String fileName)

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. private static final String OOM = "java.lang.OutOfMemoryError";  
  2. if (isOOM(arg1)) {  
  3.     SimpleDateFormat sDateFormat =  
  4.             new SimpleDateFormat("MM_dd_hh_mm_ss");  
  5.     String date = sDateFormat.format(new Date());  
  6.     File dumpfile = new File(logdir + File.separator + "oom" + date  
  7.             + ".hprof");  
  8.     Debug.dumpHprofData(dumpfile.getAbsolutePath());  
  9. }  

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public static boolean isOOM(Throwable throwable){  
  2.     if(OOM.equalsIgnoreCase(throwable.getClass().getName())){  
  3.         return true;  
  4.     }else{  
  5.         Throwable cause = throwable.getCause();  
  6.         if(cause != null){  
  7.             return isOOM(cause);  
  8.         }  
  9.         return false;  
  10.     }  
  11. }  




小结


  1. dumpsys meminfo适用场景: 查看进程的oom adj,或者dalvik/native等区域内存情况,或者某个进程或apk的内存情况,功能非常强大;

  2. procrank适用场景: 查看进程的VSS/RSS/PSS/USS各个内存指标;

  3. cat /proc/meminfo适用场景: 查看系统的详尽内存信息,包含内核情况;

  4. free适用场景: 只查看系统的可用内存;

  5. showmap适用场景: 查看进程的虚拟地址空间的内存分配情况;

  6. vmstat适用场景: 周期性地打印出进程运行队列、系统切换、CPU时间占比等情况;

  7. getprop:查看当前手机HEAP size 设定


猜你喜欢

转载自blog.csdn.net/lucky_liuxiang/article/details/71425023