第46讲 Perfetto 内存分析之Android内存管理概述

本讲是Android Camera性能分析专题的第46讲,我们介绍Perfetto内存分析之Android内存管理概述。

更多资源:

资源 描述
在线课程 极客笔记在线课程
知识星球 星球名称:深入浅出Android Camera
星球ID: 17296815
Wechat 极客笔记圈

在Android中查看某个进程某时刻的内存使用情况

可以通过dumpsys meminfo来查看某进程中各类型的内存使用情况

在Android中查看某个进程某时刻的内存使用情况

主要关注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/RSS/PSS/USS指标解释

  • 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,虚拟内存区域) 。

Linux Memory管理初探 – VMAs类型

  • 针对Anonymous VMA,只有当进程实际要去读/写VMAs时,才会按页粒度分配物理内存。比如,如果你分配了32 MB的内存,但只读/写1个字节,那么实际物理内存的使用量只会增加4KB。

  • 针对File-backed VMA,申请Buffer时就会直接申请对应大小的物理内存

  • 优化进程的内存使用量时,我们主要关注的是物理内存的使用量(RSS/PSS),虚拟内存的占用不是太重要(特别是在64bit的设备上,虚拟内存完全够用)

Linux Memory管理初探 – VMAs状态

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
…

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程

Android Camera性能分析