本讲是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
…