• 【FLY】Android内存性能优化


    一、理论基础

    1、CPU Cache

    在现代处理器中,与CPU执行代码或处理信息相比,向内存子系统保存信息或从中读取信息一般花费的时间更长。通常,在CPU执行指令或处理数据前,它会消耗相当多的空闲时间来等待从内存中取出指令和数据。处理器用不同层次的高速缓存(cache)来弥补这种缓慢的内存性能。
    当应用程序使用物理内存时,它首先与CPU的高速缓存子系统交互。现代CPU有多级高速缓存。最快的高速缓存离CPU最近(也称为L1或一级高速缓存),其容量也最小。举个例子,假设CPU只有两级高速缓存:L1和L2。当CPU请求一块内存时,处理器会检查看该块内存是否已经存在于L1高速缓存中。如果处于,CPU就可以使用。如果不在L1高速缓存中,处理器产生一个L1高速缓存不命中。然后它会检查L2高速缓存,如果数据在L2高速缓存中,那么它可以使用。如果数据不在L2高速缓存,将产生一个L2高速缓存不命中,处理器就必须到物理内存去取回信息。最终,如果处理器从不访问物理内存(因为它会在L1或者甚至L2高速缓存中发现数据)将是最佳情况。明智地使用高速缓存,例如重新排列应用程序的数据结构以及减少代码量等方法,有可能减少高速缓存不命中的次数并提高性能。

    2、内存子系统

    任何给定的Linux系统都有一定容量的RAM或物理内存。在这个物理内存中寻址时,Linux将其分成块或内存“页”。当对内存进分配或传送时,Linux操作的单位是页,而不是单个字节。在报告一些内存统计数据时,Linux内核报告的是每秒页面的数量,该值根据其运行的架构可以发生变化。
    对IA32架构而言,页面大小为4KB。极少数情况下,这些页面大小的内存块会导致极高的跟踪开销,所以,内核用更大的块来操作内存,这些块被称为HugePage(大页面)。它们的容量为2048KB,而不是4KB,这大大降低了管理庞大内存的开销。如果HugePage不能完全被填满,就会浪费相当多的内存。一个半填充的普通页面浪费2KB内存,而一个半填充的HugePage就会浪费1024KB的内存。
    Linux内核可以分散收集这些物理页面,向应用程序呈现出一个精心设计的虚拟内存空间。
    在顶层,操作系统决定如何利用交换内存和物理内存。它决定应用程序的哪一块地址空间将被放到物理内存中,即所谓的驻留集。不属于驻留集却又被应用程序使用的其他内存将被交换到磁盘。由应用程序决定要向操作系统请求多少内存,即所谓的虚拟集。应用程序可以通过调用malloc进行显式分配,也可以通过使用大量的堆栈或库进行隐式分配。应用程序还可以分配被其自身或其他应用程序使用的共享内存。

    3、Swap

    所有系统RAM芯片的物理内存容量都是固定的。即使应用程序需要的内存容量大于可用的物理内存,Linux内核仍然允许这些程序运行。Linux内核使用硬盘作为临时存储器,这个硬盘空间被称为交换分区(swap space)。
    尽管交换是让进程运行的极好的方法,但它却慢的要命。与使用物理内存相比,应用程序使用交换的速度可以慢到一千倍。如果系统性能不佳,确定系统使用了多少交换通常是有用的。
    有时候,系统没有足够的内存来处理所有的运行进程。当一个进程的内存被保存下来,以便为之前已经交换到硬盘的应用程序腾位置时,就会出现高频率的换入和换出。如果有两个运行程序需要的内存量都超过了系统可提供的量,后果就会很糟糕。比如,两个进程都在使用大量内存,且它们都试图同时运行,而每个进程都可以导致另一个的内存被写交换。当一个程序需要一块内存时,它就会把另一个程序需要的一块内存踢出去。而当另一个应用程序开始运行时,它又会把第一个程序正在使用的一块内存踢出去,并等待自己的内存块从交换分区加载进来。这可能会导致两个应用程序出现停顿,以等待它们的内存从交换分区取回,然后才能继续执行。只要一个程序进步一点点,它就会将另一个进程使用的内存交换出去,从而导致这个程序慢下来。这种情况被称为颠簸。发生颠簸时,系统会花大量的时间将内存读出或写入交换分区,系统性能就会急剧下降。

    4、Cache&Buffer

    如果系统物理内存容量超过了应用程序的需求,Linux就会在物理内存中缓存(cache)近期使用过的文件,这样,后续访问这些文件时就不用去访问硬盘了。对要频繁访问硬盘的应用程序来说,这可以显著加速其速度,显然,对经常启动的应用程序而言,这是特别有用的。应用程序首次启动时,它需要从硬盘读取;但是,如果应用程序留在缓存中,那它就可以从更快速的物理内存读取。
    除了高速缓存,Linux还使用了额外的存储作为缓冲区(buffer)。为了进一步优化应用程序,Linux为需要被写回硬盘的数据预留了存储空间。这些预留空间被称为缓冲区。如果应用程序要将数据写回硬盘,通常需要花费较长时间,Linux让应用程序立刻继续执行,但将文件数据保存到内存缓冲区。在之后的某个时刻,缓冲区被刷新到硬盘,而应用程序可以立即继续。
    高速缓存和缓冲区的使用使得系统内空闲的内存很少。默认情况下,Linux试图尽可能多的使用内存。如果Linux侦测到有空闲内存,它就会将应用程序和数据缓存到这些内存以加速未来的访问。由于访问内存的速度比访问硬盘的速度快了几个数量级,因此,这就可以显著地提升整体性能。如果系统需要缓存空间做更重要的事情,那么缓存空间将被擦除并交给系统。之后,对原来被缓存对象的访问就需要转向硬盘来满足。

    5、Active&Inactive

    活跃内存(Active)是指当前被进程使用的内存。不活跃内存(Inactive)是指已经被分配了,但暂时还未使用的内存。这两种类型的内存没有本质上的区别。需要时,Linux找出进程最近最少使用的内存页面,并将它们从活跃列表移动到不活跃列表。当要选择把哪个内存页交换到硬盘时,内核就从不活跃内存列表中进行选择。

    6、高端内存

    对拥有1GB或更多物理内存的32位处理器(比如IA32)来说,Linux管理内存时必须将其分为高端与低端内存。高端内存不能直接被Linux内核访问,而是必须在使用前映射到低端内存范围内。64位处理器(比如AMD64)没有这个问题,因为它们可以直接寻址当前系统可用的额外内存。

    7、内核内存分片

    除了应用程序需要分配内存外,Linux内核也会为了记账的目的消耗一定量的内存。记账包括,比如跟踪从网络或磁盘I/O来的数据,以及跟踪哪些进程正在运行,哪些正在休眠。为了管理记账,内核有一系列缓存,包含了一个或多个内存分片。每个分片为一组对象,个数可以是一个或多个。内核消耗的内存分片数量取决于使用的是Linux内核的哪些部分,而且还可以随着机器负载类型的变化而变化。

    二、测试分析工具

    1、proc

    /proc/meminfo
    meminfo,提供了很多内存相关的数据,下面是详细说明。
    MemTotal: 3131924 kB
    系统总内存,dmesg中有下面的Log:
    Memory: 2724372K/4629476K available (13372K kernel code, 1978K rwdata, 6112K rodata, 6144K init, 9509K bss, 1503696K reserved, 401408K cma-reserved)
    Freeing unused kernel memory: 6144K
    分子2724372K表示available内存,分母4629476K表示物理内存。
    available内存,包括kernel code、rwdata、rodata、init、bss。
    available内存=物理内存-reserved-cma-reserved
    MemTotal=available内存+cma-reserved+Freeing unused kernel memory
    MemFree: 359048 kB
    未使用内存
    MemFree=MemTotal-已使用内存
    MemAvailable: 853928 kB
    可用内存
    MemAvailable=MemFree+可回收内存
    Buffers: 10104 kB
    块设备缓存(Buffers可能只包括块设备的元数据,缓存移到了Cached)
    Cached: 485204 kB
    文件页缓存,不包括SwapCached,Cached=Mapped+Unmapped
    SwapCached: 8520 kB
    交换区缓存,曾被SwapOut,后来又被SwapBack,用于AnonPages和Shmem
    Active: 639944 kB
    活跃内存,一般是不可回收内存,Active=Active(anon)+Active(file)
    Inactive: 757376 kB
    不活跃内存,一般是可回收内存,Inactive=Inactive(anon)+Inactive(file)
    Active(anon): 453940 kB
    匿名页活跃内存
    Inactive(anon): 453416 kB
    匿名页不活跃内存
    Active(file): 186004 kB
    文件页活跃内存
    Inactive(file): 303960 kB
    文件页不活跃内存
    Unevictable: 2944 kB
    禁止换出的内存,不能pageout/swapout
    Mlocked: 2944 kB
    锁定内存,同Unevictable
    SwapTotal: 1048572 kB
    交换区总内存,SwapTotal=SwapFree+SwapUsed
    SwapFree: 690440 kB
    交换区剩余内存
    Dirty: 1716 kB
    脏数据的大小,等待写回磁盘
    Writeback: 0 kB
    正在写回磁盘的数据大小
    AnonPages: 903512 kB
    匿名页的大小,不是文件页,生命周期跟随用户进程
    Mapped: 372600 kB
    内存映射,被用户进程关联的文件页缓存
    Shmem: 3032 kB
    共享内存,基于tmpfs,属于file-backed pages,不是anonymous pages
    Slab: 193500 kB
    slab分配的连续物理内存,高速缓存,解决内存碎片问题
    SReclaimable: 46500 kB
    slab中可回收内存
    SUnreclaim: 147000 kB
    slab中不可回收内存
    Slab=SReclaimable+SUnreclaim
    KernelStack: 39792 kB
    内核栈的大小,内核态
    PageTables: 67200 kB
    把虚拟地址翻译成物理地址的页表管理模块的内存
    NFS_Unstable: 0 kB
    NFS客户端缓存,已发送给服务端,但尚未确认服务端是否写入了磁盘
    Bounce: 0 kB
    低端内存中对高端内存的缓存
    WritebackTmp: 0 kB
    Memory used by FUSE for temporary writeback buffers
    CommitLimit: 2614532 kB
    系统可分配的总内存,CommitLimit = ([total RAM pages] - [total huge TLB pages]) * overcommit_ratio / 100 + [total swap pages]
    Committed_AS: 161196364 kB
    系统已分配的总内存
    VmallocTotal: 263061440 kB
    vm支持的总内存
    VmallocUsed: 105152 kB
    vm已分配的内存
    VmallocChunk: 0 kB
    默认值(vmalloc可用的最大的连续内存块的大小)
    查看vmalloc数据的命令:cat /proc/vmallocinfo
    CmaTotal: 401408 kB
    连续内存区域总内存
    CmaFree: 289196 kB
    连续内存区域剩余内存
    /proc/swaps
    swaps,提供了swap分区的信息,如下图所示。
    在这里插入图片描述

    /proc/buddyinfo
    buddyinfo,提供了内存管理机制buddy的信息,buddy以页为单位进行内存管理,如下图所示,Node表示NUMA节点,zone表示不同类型的内存区域,后面共11列数字表示不同大小内存块的空闲个数,其中第1列表示1个内存页,第2列表示2个内存页,后面按照2的等比数列增长。
    在这里插入图片描述

    /proc/pagetypeinfo
    pagetypeinfo,是对buddyinfo的一个细化,如下图所示。
    在这里插入图片描述

    /proc/slabinfo
    slab内存管理机制,以字节为单位,基于对象,管理小内存,如下图所示。
    在这里插入图片描述

    统计slab大小的命令:cat /proc/slabinfo | awk ‘BEGIN{sum=0;}{sum=sum+$3*$4;}END{print sum/1024}’
    /proc/zoneinfo
    zoneinfo,提供了内存区域更多的信息,如下图所示。
    在这里插入图片描述

    /proc/iomem
    iomem,表示物理设备地址映射的关系,如下图所示,是System RAM相关的部分数据,冒号前表示地址范围,冒号后表示类型。
    在这里插入图片描述

    /proc/vmallocinfo
    vmallocinfo,提供了具体的虚拟内存分配数据,如下图所示。
    在这里插入图片描述

    统计vmallocinfo中vmalloc类型的数据大小的命令:grep vmalloc /proc/vmallocinfo | awk ‘BEGIN{sum=0;}{sum=sum+$2}END{print sum/1024}’
    /proc/vmstat
    vmstat,提供了虚拟内存的分类汇总数据,如下图所示。
    在这里插入图片描述

    /proc/PID
    /proc目录下有以各个进程号(PID)命名的目录,里面跟踪了各个进程的详细信息。
    maps,提供了关于如何使用进程虚拟地址空间的信息,如下图所示。
    在这里插入图片描述

    smaps提供了比maps更为详细的数据,如下图所示。
    在这里插入图片描述

    另外,常见的目录还有status、statm、stat。

    2、top

    usage: top [-Hbq] [-k FIELD,] [-o FIELD,] [-s SORT] [-n NUMBER] [-m LINES] [-d SECONDS] [-p PID,] [-u USER,]
    Show process activity in real time.
    -H      Show threads
    -k      Fallback sort FIELDS (default -S,-%CPU,-ETIME,-PID)
    -o      Show FIELDS (def PID,USER,PR,NI,VIRT,RES,SHR,S,%CPU,%MEM,TIME+,CMDLINE)
    -O      Add FIELDS (replacing PR,NI,VIRT,RES,SHR,S from default)
    -s      Sort by field number (1-X, default 9)
    -b      Batch mode (no tty)
    -d      Delay SECONDS between each cycle (default 3)
    -m      Maximum number of tasks to show
    -n      Exit after NUMBER iterations
    -p      Show these PIDs
    -u      Show these USERs
    -q      Quiet (no header lines)
    Cursor LEFT/RIGHT to change sort, UP/DOWN move list, space to force
    update, R to reverse sort, Q to exit.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    如下图所示,是top命令的默认输出,内存相关的关键字段包括:Mem、Swap、VIRT、RES、SHR、%MEM。
    在这里插入图片描述

    3、ps

    usage: ps [-AadefLlnwZ] [-gG GROUP,] [-k FIELD,] [-o FIELD,] [-p PID,] [-t TTY,] [-uU USER,]
    List processes.
    Which processes to show (selections may be comma separated lists):
    -A      All processes
    -a      Processes with terminals that aren't session leaders
    -d      All processes that aren't session leaders
    -e      Same as -A
    -g      Belonging to GROUPs
    -G      Belonging to real GROUPs (before sgid)
    -p      PIDs (--pid)
    -P      Parent PIDs (--ppid)
    -s      In session IDs
    -t      Attached to selected TTYs
    -T      Show threads
    -u      Owned by USERs
    -U      Owned by real USERs (before suid)
    Output modifiers:
    -k      Sort FIELDs in +increasing or -decreasting order (--sort)
    -M      Measure field widths (expanding as necessary)
    -n      Show numeric USER and GROUP
    -w      Wide output (don't truncate fields)
    Which FIELDs to show. (Default = -o PID,TTY,TIME,CMD)
    -f      Full listing (-o USER:12=UID,PID,PPID,C,STIME,TTY,TIME,ARGS=CMD)
    -l      Long listing (-o F,S,UID,PID,PPID,C,PRI,NI,ADDR,SZ,WCHAN,TTY,TIME,CMD)
    -o      Output FIELDs instead of defaults, each with optional :size and =title
    -O      Add FIELDS to defaults
    -Z      Include LABEL
    Command line -o fields:
    ARGS     CMDLINE minus initial path     CMD  Command (thread) name (stat[2])
    CMDLINE  Command line (argv[])          COMM Command filename (/proc/$PID/exe)
    COMMAND  Command file (/proc/$PID/exe)  NAME Process name (argv[0] of $PID)
    Process attribute -o FIELDs:
    ADDR  Instruction pointer               BIT   Is this process 32 or 64 bits
    CPU   Which processor running on        ETIME   Elapsed time since PID start
    F     Flags (1=FORKNOEXEC 4=SUPERPRIV)  GID     Group id
    GROUP Group name                        LABEL   Security label
    MAJFL Major page faults                 MINFL   Minor page faults
    NI    Niceness (lower is faster)
    PCPU  Percentage of CPU time used       PCY     Android scheduling policy
    PGID  Process Group ID
    PID   Process ID                        PPID    Parent Process ID
    PRI   Priority (higher is faster)       PSR     Processor last executed on
    RGID  Real (before sgid) group ID       RGROUP  Real (before sgid) group name
    RSS   Resident Set Size (pages in use)  RTPRIO  Realtime priority
    RUID  Real (before suid) user ID        RUSER   Real (before suid) user name
    S     Process state:
    R (running) S (sleeping) D (device I/O) T (stopped)  t (traced)
    Z (zombie)  X (deader)   x (dead)       K (wakekill) W (waking)
    SCHED Scheduling policy (0=other, 1=fifo, 2=rr, 3=batch, 4=iso, 5=idle)
    STAT  Process state (S) plus:
    < high priority          N low priority L locked memory
    s session leader         + foreground   l multithreaded
    STIME Start time of process in hh:mm (size :19 shows yyyy-mm-dd hh:mm:ss)
    SZ    Memory Size (4k pages needed to completely swap out process)
    TCNT  Thread count                      TID     Thread ID
    TIME  CPU time consumed                 TTY     Controlling terminal
    UID   User id                           USER    User name
    VSZ   Virtual memory size (1k units)    %VSZ    VSZ as % of physical memory
    WCHAN What are we waiting in kernel for
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    ps命令和内存相关的关键字包括:RSS、SZ、VSZ、%VSZ。ps -A -O RSS -O SZ -O VSZ -O %VSZ命令的输出如下图所示。
    在这里插入图片描述

    4、free

    usage: free [-bkmgt]
    Display the total, free and used amount of physical memory and swap space.
    -bkmgt  Output units (default is bytes)
    -h      Human readable
    
    • 1
    • 2
    • 3
    • 4

    free,如下图所示,可以看到Mem与Swap的内存使用情况。
    在这里插入图片描述

    5、vmstat

    vmstat,可以统计虚拟内存信息,其中包括memory和swap,memory如swpd、free、buff、cache,swap如si、so。
    usage: vmstat [-n] [DELAY [COUNT]]
    Print virtual memory statistics, repeating each DELAY seconds, COUNT times.
    (With no DELAY, prints one line. With no COUNT, repeats until killed.)
    Show processes running and blocked, kilobytes swapped, free, buffered, and
    cached, kilobytes swapped in and out per second, file disk blocks input and
    output per second, interrupts and context switches per second, percent
    of CPU time spent running user code, system code, idle, and awaiting I/O.
    First line is since system started, later lines are since last line.
    -n      Display the header only once
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    如下图所示,是vmstat中DELAY为1的输出。
    在这里插入图片描述

    6、procrank

    Usage: procrank [ -W ] [ -v | -r | -p | -u | -s | -h ]
    -v  Sort by VSS.
    -r  Sort by RSS.
    -p  Sort by PSS.
    -u  Sort by USS.
    -s  Sort by swap.
    (Default sort order is PSS.)
    -R  Reverse sort order (default is descending).
    -c  Only show cached (storage backed) pages
    -C  Only show non-cached (ram/swap backed) pages
    -k  Only show pages collapsed by KSM
    -w  Display statistics for working set only.
    -W  Reset working set of all processes.
    -o  Show and sort by oom score against lowmemorykiller thresholds.
    -h  Display this help screen.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    procrank,默认按PSS降序排列各个进程的内存使用情况,如下图所示。
    在这里插入图片描述

    最后还有汇总数据,如下图所示。
    在这里插入图片描述

    源码位置:android/system/extras/procrank

    7、procmem

    Usage: procmem [ -w | -W ] [ -p | -m ] [ -h ] pid
    -w  Displays statistics for the working set only.
    -W  Resets the working set of the process.
    -p  Sort by PSS.
    -m  Sort by mapping order (as read from /proc).
    -h  Hide maps with no RSS.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    procmem,比procrank更详细的记录各个进程内部的内存使用情况,如下图所示。
    在这里插入图片描述

    最后还有汇总数据,如下图所示。
    在这里插入图片描述

    源码位置:android/system/extras/procmem

    8、librank

    Usage: librank [ -P | -L ] [ -v | -r | -p | -u | -s | -h ]
    Sort options:
    -v  Sort processes by VSS.
    -r  Sort processes by RSS.
    -p  Sort processes by PSS.
    -u  Sort processes by USS.
    -s  Sort processes by swap.
    (Default sort order is PSS.)
    -a  Show all mappings, including stack, heap and anon.
    -P /path  Limit libraries displayed to those in path.
    -R  Reverse sort order (default is descending).
    -m [r][w][x] Only list pages that exactly match permissions
    -c  Only show cached (storage backed) pages
    -C  Only show non-cached (ram/swap backed) pages
    -k  Only show pages collapsed by KSM
    -h  Display this help screen.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    librank,以lib为单位统计使用了lib的各个进程的内存数据,如下图所示。
    在这里插入图片描述

    源码位置:android/system/extras/librank

    9、pmap

    usage: pmap [-xq] [pids...]
    Reports the memory map of a process or processes.
    -x Show the extended format
    -q Do not display some header/footer lines
    
    • 1
    • 2
    • 3
    • 4

    pmap,类似于proc下面的map数据,如下图所示,是使用了-x的输出。
    在这里插入图片描述

    最后还有汇总数据,如下图所示。
    在这里插入图片描述

    10、showmap

    showmap [-t] [-v] [-c] [-q] 
    -t = terse (show only items with private pages)
    -v = verbose (don't coalesce maps with the same name)
    -a = addresses (show virtual memory map)
    -q = quiet (don't show error if map could not be read)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    showmap,可以显示某个进程的map数据,如下图所示。
    在这里插入图片描述

    最后还有汇总数据,如下图所示。
    在这里插入图片描述

    源码位置:android/system/extras/showmap

    11、showslab

    usage: showslab [options]
    options:
    -s S   specify sort criteria S
    -h     display this help
    Valid sort criteria:
    a: number of Active objects
    c: Cache size
    l: number of sLabs
    n: Name
    o: number of Objects
    p: objects Per slab
    s: object Size
    u: cache Utilization
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    showslab,显示slab相关数据,如下图所示的默认输出。
    在这里插入图片描述

    源码位置:android/system/extras/showslab

    12、dumpcache

    dumpcache,打印每个文件的页缓存数据,如下图所示。
    在这里插入图片描述

    源码位置:android/system/extras/pagecache

    13、Android Dumpsys

    Android命令dumpsys meminfo可以降序打印各个进程的内存使用情况,以及整体上的内存统计,如果后面跟着包名或进程号,则可以打印指定进程的详细的内存相关的数据。

    meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]
    -a: include all available information for each process.
    -d: include dalvik details.
    -c: dump in a compact machine-parseable representation.
    -s: dump only summary of application memory usage.
    -S: dump also SwapPss.
    --oom: only show processes organized by oom adj.
    --local: only collect details locally, don't call process.
    --package: interpret process arg as package, dumping all
    processes that have loaded that package.
    --checkin: dump data for a checkin
    --proto: dump data to proto
    If [process] is specified it can be the name or
    pid of a specific process to dump.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    dumpsys meminfo,大致输出如下图所示的内容。其中,LostRAM可能与DMA有关,可以查看/sys/kernel/debug/dma_buf目录中的bufinfo和dmaprocs。
    在这里插入图片描述

    如下图所示,是打印的某个进程的数据。
    在这里插入图片描述

    源码位置:android/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    14、Android Profiler

    Android Studio自带的Profiler工具可以分析内存问题,界面大致如下图所示。
    在这里插入图片描述

    profiler详细用法请参考下面的链接。
    https://developer.android.google.cn/studio/profile/memory-profiler

    15、Android Hprof

    在Android中可以使用am命令的dumpheap选项生成hprof文件,然后使用Android Studio分析hprof内存数据。

    dumpheap [--user  current] [-n] [-g]  
    Dump the heap of a process.  The given  argument may
    be either a process name or pid.  Options are:
    -n: dump native heap instead of managed heap
    -g: force GC before dumping the heap
    --user  | current: When supplying a process name,
    specify user of process to dump; uses current user if not specified.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    16、Android ASan

    Android中的Address Sanitizer是一个内存检查工具,可以分析下面几类问题。

    • Use after free (dangling pointer dereference)
    • Heap buffer overflow
    • Stack buffer overflow
    • Global buffer overflow
    • Use after return
    • Use after scope
    • Initialization order bugs
    • Memory leaks
      ASan详细用法请参考下面的链接。
      https://developer.android.google.cn/ndk/guides/asan
      https://developer.android.google.cn/ndk/guides/hwasan
      https://developer.android.google.cn/ndk/guides/gwp-asan
      https://github.com/google/sanitizers/wiki/AddressSanitizer

    17、Android Malloc Hook

    Android支持malloc hook,即libc的preload技术,可以跟踪内存使用情况,详细用法请参考下面的说明文档。
    android/bionic/libc/malloc_debug/README
    android/bionic/libc/malloc_hooks/README

    三、其它工具

    sysstat/sar
    oprofile
    procinfo
    slabtop
    memprof
    ipcs
    valgrind/cachegrind/kcachegrind

    四、调优

    1、coding

    编写代码时注意内存相关的问题,例如C/C++的内存动态管理,Java的GC Root以及内部类持有的外部类引用等。

    2、隐式资源分配

    当我们调用一些函数时,函数内部会隐式地进行内存等资源分配,例如file.open等,这个地方需要格外注意。

    3、代码静态检查

    通过代码静态检查工具,发现潜在的问题点。

    4、oom

    关注oom、lmkd、kswapd。

  • 相关阅读:
    Dev的splitContainerControl控件重要属性
    【其他专题】好用的截图(包括动图gif)软件分享
    DreamScene2 免费WIndows 动态桌面壁纸播放软件启动无响应失败问题解决及安装使用帮助
    第二证券|超300家机构关注两大赛道龙头,透露市场增长及发展方向
    论文解读(ClusterSCL)《ClusterSCL: Cluster-Aware Supervised Contrastive Learning on Graphs》
    网络协议--TCP:传输控制协议
    springboot自动装配
    67. SAP ABAP 监控用户事物码和程序执行的工具介绍
    MyBatis中如何动态拼接Sql字符串呢?
    RabbitMQ 安装和使用Demo
  • 原文地址:https://blog.csdn.net/iEearth/article/details/126382652