本讲是android camera性能分析专题的第46讲,我们介绍perfetto内存分析之android内存管理概述。
更多资源:
资源 | 描述 |
---|---|
在线课程 | |
知识星球 | 星球名称:深入浅出android camera 星球id: 17296815 |
极客笔记圈 |
在android中查看某个进程某时刻的内存使用情况
可以通过dumpsys meminfo来查看某进程中各类型的内存使用情况
主要关注private dirty这一列,可以看出
- systemui进程占用java heap(dalvik)为9032kb
-
systemui进程占用native heap为16804kb
vss/rss/pss/uss指标解释
内存指标类型 | 描述 |
---|---|
vss | virtual set size,虚拟耗用内存(包含共享库占用的内存) |
rss | resident set size,实际使用物理内存(包含共享库占用的内存) |
pss | proportional set size ,实际使用的物理内存(按比例平均分配共享库占用的内存) |
uss | unique set size,进程独自占用的物理内存(不包含共享库占用的内存) |
一般来说,某进程各类型内存占用大小的规律是:vss >= rss >= pss >= uss
可以通过procrank命令来查看(需要root)
procrank | grep -ie "cmdline|camera"
pid vss rss pss uss swap pswap uswap zswap cmdline
387 4386288k 132156k 123469k 121308k 54092k 54092k 54092k 14798k /vendor/bin/hw/android.hardware.camera.provider@2.4-service_64
597 61172k 13640k 8649k 6040k 1768k 1768k 1768k 483k /system/bin/cameraserver
下图显示了三个进程,并且每个页面都映射到了它的虚拟地址空间。这些页面已被标记为 a、b 或 c 类型,其中:
- a = 映射到 dram 物理页的私有内存
-
b = 被一个或多个其他进程映射并共享的共享内存(如共享库中的代码)
-
c = 已分配但从未使用的内存
- vss = a b c
-
rss = a b
-
uss = a
-
pss = a b/n 其中 n 是共享的进程数
比如,计算三个进程的pss:
- pss(p1) = 2(a) 3/3(b) 2/2(b) = 4
-
pss(p2) = 2(a) 3/3(b) 2/2(b) = 4
-
pss(p3) = 2(a) 3/3(b) = 3
linux memory管理初探 – vmas类型
从linux内核的角度来看,内存被分割成相等大小的块,称为page,通常每个page大小为4kb。
linux内核管理进程地址空间使用的数据结构是struct vm_area_struct,简称vma (virtual memory area,虚拟内存区域) 。
- 针对anonymous vma,只有当进程实际要去读/写vmas时,才会按页粒度分配物理内存。比如,如果你分配了32 mb的内存,但只读/写1个字节,那么实际物理内存的使用量只会增加4kb。
-
针对file-backed vma,申请buffer时就会直接申请对应大小的物理内存
-
优化进程的内存使用量时,我们主要关注的是物理内存的使用量(rss/pss),虚拟内存的占用不是太重要(特别是在64bit的设备上,虚拟内存完全够用)
linux memory管理初探 – vmas状态
- resident:page已经map到物理内存
- clean (only for file-backed pages):page里面存放的内容与disk上存放的内容完全一样,在低内存情况下,很容易被kernel evict掉(如果不使用)
-
dirty:page里面存放的内容没有备份,因此无法被kernel回收,但可以被swap到disk
-
swapped:已经被swap到disk上的dirty page,在遇到page fault时会被重新swap in。
-
not present:重来没有发生过page fault的page,或者clean page马上要被回收。
通过c的malloc(), c 的new() 或java的new x() 申请的都是anonymous且dirty的内存,因此,内存优化时需要优先考虑减少dirty状态的内存用量,因为他无法被临时回收。
rss high watermark
如果想看某个进程自启动以来的最大 rss 使用量,可以看vmhwm(rss high watermark)
cat /proc/387/status |grep vm
vmpeak: 4577168 kb
vmsize: 3682084 kb
…
vmhwm: 154692 kb
vmrss: 59728 kb
…