Android 内存之监控篇

2019-10-08  本文已影响0人  PuHJ

一、前言

内存问题主要会造成如下几个影响。第一、会发生OOM等异常,因为每个对象都会占用一定的内存,内存过多会影响对象的分配失败,严重者会导致设备重启。第二、内存过大,导致系统回收缓存内存,以及会加快GC频率,从而导致应用卡顿。

内存的监控就尤为的重要。下面从几个方面来看Android对内存的监控,从而有助于观察内存变化。

二、free

free是轻量级的查看设备整体内存情况,具体例子如下:

root@debian7:/proc/10# free
             total       used       free     shared    buffers     cached
Mem:       3044840     247692    2797148          0      19896     110084
-/+ buffers/cache:     117712    2927128
Swap:       901116          0     901116

其中total = used + free,单位KB。
对于-/+ buffers/cache行,是从有无缓冲来看。117712 = used - buffers - cached.
2927128 = free + buffers + cached.

三、/proc/meminfo文件

/proc/meminfo是free的加强版,free中的数据也是从/proc/meminfo而来的。

root@debian7:/proc/10# cat /proc/meminfo
MemTotal:        3044840 kB  // RAM内存总大小
MemFree:         2797520 kB  // RAM可用内存大小
Buffers:           19912 kB  // Buffers缓存,文件缓存
Cached:           110084 kB  // Cached缓存大小
SwapCached:            0 kB
Active:            97184 kB // 在活跃下的缓冲或高速缓冲存储器页面文件的大小
Inactive:          94008 kB // 非活跃下的缓冲或高速缓冲存储器页面文件的大小
Active(anon):      61312 kB // Active = Active(anon) + Active(file)
Inactive(anon):     6008 kB
Active(file):      35872 kB
Inactive(file):    88000 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:        901116 kB
SwapFree:         901116 kB
Dirty:                 0 kB // 等待被写回到磁盘的内存大小。
Writeback:             0 kB // 正在被写回到磁盘的内存大小。
AnonPages:         61188 kB
Mapped:            24656 kB // 文件通过mmap分配的内存
Shmem:              6132 kB
Slab:              20412 kB //  内核数据结构缓存的大小。Linux中的Slab内存分配策略,相对于伙伴系统分配
SReclaimable:       6288 kB
SUnreclaim:        14124 kB
KernelStack:        1000 kB
PageTables:         4656 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     2423536 kB
Committed_AS:     535828 kB
VmallocTotal:   34359738367 kB  // 总分配的虚拟地址空间
VmallocUsed:      158760 kB  // 已分配的虚拟地址空间
VmallocChunk:   34359576572 kB
HardwareCorrupted:     0 kB
AnonHugePages:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       45056 kB
DirectMap2M:     2076672 kB
DirectMap1G:     1048576 kB

四、vmstat

vmstat命令可以查看内存、IO和CPU等信息。

语法命令:

Usage: vmstat [ -n iterations ] [ -d delay ] [ -r header_repeat ]
    -n iterations     数据循环输出的次数
    -d delay          两次数据间的延迟时长(单位:S)
    -r header_repeat  循环多少次,再输出一次头信息行

vmstat例子:

root@debian7:/proc/10# vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 0  0      0 2797396  19960 110084    0    0     1     0   13   25  0  0 100  0

procs 程序

memory 内存

swap swap空间,内存够用时,si和so值都为0

IO

system

cpu

五、/proc/[PID]/status

root@p212:/data/dropbear # cat /proc/4943/status
Name:   XXXXX
State:  S (sleeping) : 状态
Tgid:   4943 :线程组ID
Pid:    4943 :进程ID,同TGID,说明是主线程
PPid:   3769 :父进程ID
TracerPid:      0
Uid:    10039   10039   10039   10039
Gid:    10039   10039   10039   10039
Ngid:   0
FDSize: 64 :FDSize是当前分配过的文件描述符数量
Groups: 3003 9997 50039 : groups表示启动这个进程的用户所在的组.
VmPeak:  1503968 kB :当前进程运行过程中占用内存的峰值
VmSize:   878224 kB  :虚拟内存大小
VmLck:         0 kB
VmPin:         0 kB
VmHWM:     40040 kB :分配到物理内存的峰值
VmRSS:     38120 kB : 虚拟内存驻留集合大小
VmData:   134084 kB :进程数据段的大小
VmStk:      8196 kB : 进程堆栈段的大小
VmExe:        20 kB
VmLib:     69224 kB
VmPTE:       440 kB
VmSwap:        0 kB : 进程占用Swap的大小.
Threads:        22 :线程数量
SigQ:   0/2462
SigPnd: 0000000000000000 : 存储了该线程的待处理信号
ShdPnd: 0000000000000000 : 存储了该线程组的待处理信号
SigBlk: 0000000000001204 : 存放被阻塞的信号
SigIgn: 0000000000000000 : 存放可被忽略的信号
SigCgt: 00000002000094f8
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000000000000000
Seccomp:        0
Cpus_allowed:   f
Cpus_allowed_list:      0-3
voluntary_ctxt_switches:        358 : 进程主动切换上下文的次数(资源得不到等)
nonvoluntary_ctxt_switches:     400 : 进程被动切换上下文的次数.

六、Android#Runtime

Android中提供了一些接口,供使用者调用,可定时的采集以下几种内存情况,从而判断当前进程内存情况。

        Runtime runtime = Runtime.getRuntime();
        long javaMax = runtime.maxMemory();  //  JVM可分配的最大内存
        long javaTotal = runtime.totalMemory();  //  当前分配的内存
        long javaUsed = javaTotal - runtime.freeMemory();  //  当前使用的内存
        
        float proportion = (float) javaUsed / javaMax;
        Log.e("TAG", "onResume: javaMax="+javaMax+";javaTotal="+javaTotal+";javaUsed="+javaUsed+";proportion="+proportion);

七、Android#onLowMemory

在Android4.0中提供了一些监听内存的接口OnLowMemory和onTrimMemory

【一】、OnLowMemory

OnLowMemory是ComponentCallbacks接口中的方法,当系统内存不足,要被杀死后台程序时,会调用该方法。

可用在Application、Activity、Fragement、Service和ContentProvider中

【二】、onTrimMemory

因为OnLowMemory的接口太简单了,并没有提供内存的状态,在ComponentCallbacks2中丰富了回调了接口。

public interface ComponentCallbacks2 extends ComponentCallbacks {

    /** @hide */
    @IntDef(prefix = { "TRIM_MEMORY_" }, value = {
            TRIM_MEMORY_COMPLETE,
            TRIM_MEMORY_MODERATE,
            TRIM_MEMORY_BACKGROUND,
            TRIM_MEMORY_UI_HIDDEN,
            TRIM_MEMORY_RUNNING_CRITICAL,
            TRIM_MEMORY_RUNNING_LOW,
            TRIM_MEMORY_RUNNING_MODERATE,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface TrimMemoryLevel {}

    static final int TRIM_MEMORY_COMPLETE = 80;
    
    static final int TRIM_MEMORY_MODERATE = 60;
   
    static final int TRIM_MEMORY_BACKGROUND = 40;
    
    static final int TRIM_MEMORY_UI_HIDDEN = 20;

    static final int TRIM_MEMORY_RUNNING_CRITICAL = 15;

    static final int TRIM_MEMORY_RUNNING_LOW = 10;

    static final int TRIM_MEMORY_RUNNING_MODERATE = 5;

    void onTrimMemory(@TrimMemoryLevel int level);
}

同onLowMemory一致,也可用在Application、Activity、Fragement、Service和ContentProvider中。

八、dumpsys

通过adb shell dumpsys meminfo [pid | 包名] 可以查看单个APP内存情况

如下:

Applications Memory Usage (kB):
Uptime: 31564143 Realtime: 31564143

** MEMINFO in pid 30712 [XXX] **
                   Pss  Private  Private  Swapped     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap     2196     2092        0        0     6144     4855     1288
  Dalvik Heap     1517     1396        0        0     3873     2449     1424
 Dalvik Other      373      372        0        0
        Stack      132      132        0        0
       Ashmem        2        0        0        0
    Other dev        5        0        4        0
     .so mmap     1148       96      156        0
    .apk mmap      326        0       28        0
    .ttf mmap       88        0       76        0
    .dex mmap     2844        4     2840        0
    .oat mmap     1204        0      164        0
    .art mmap     1321      476      368        0
   Other mmap       11        8        0        0
    GL mtrack     2960     2960        0        0
      Unknown      121      120        0        0
        TOTAL    14248     7656     3636        0    10017     7304     2712

 App Summary
                       Pss(KB)
                        ------
           Java Heap:     2240
         Native Heap:     2092
                Code:     3364
               Stack:      132
            Graphics:     2960
       Private Other:      504
              System:     2956

               TOTAL:    14248      TOTAL SWAP (KB):        0

 Objects
               Views:       15         ViewRootImpl:        1
         AppContexts:        2           Activities:        1
              Assets:        2        AssetManagers:        2
       Local Binders:        9        Proxy Binders:       12
       Parcel memory:        3         Parcel count:       14
    Death Recipients:        0      OpenSSL Sockets:        0

 SQL
         MEMORY_USED:        0
  PAGECACHE_OVERFLOW:        0          MALLOC_SIZE:        0

第一部分主要字段解析:
App Summary主要字段解析:
Objects主要字段解析:
上一篇下一篇

猜你喜欢

热点阅读