VSS/RSS/PSS/USS
-
VSS:Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)。(reported as VSZ from ps) is the total accessible address space of a process.
-
RSS:Resident Set Size 实际使用物理内存(包含共享库占用的内存)。
resident set size, the non-swapped physical memory that a task has used (in kilobytes). (alias rssize, rsz). RSS is the total memory actually held in RAM for a process.
- It does not include memory that is swapped out.
- It does include memory from shared libraries as long as the pages from those libraries are actually in memory.
- It does include all stack and heap memory.
-
PSS:Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存),但是 PSS 并不是在所有的Linux系统中都有提供的,比如 ps 命令中就没有PSS值,而 Android 的dumpsys命令就可以看到进程的PSS值。
adb shell dumpsys meminfo <pid>
-
USS:Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)
一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS
Overview of Android Memory Management
dumpsys meminfo
-
Private (Clean and Dirty) RAM
-
这是仅由您的进程使用的内存。这是您的应用进程销毁后系统可以回收的 RAM 容量。通常情况下,最重要的部分是
Private Dirty RAM
,它的开销最大,因为只有您的进程使用它,而且其内容仅存在于 RAM 中,所以无法通过分页机制映射到硬盘(因为 Android 不使用swap)。您进行的所有 Dalvik 和原生堆分配都将是私有脏 RAM;您与 Zygote 进程共享的 Dalvik 和原生分配则是共享脏 RAM(shared dirty RAM
)。
Proportional Set Size (PSS)
-
这是对应用 RAM 占用情况的衡量,考虑了在进程之间共享 RAM 页的情况。您的进程独占的 RAM 页会直接计入其 PSS 值,而与其他进程共享的 RAM 页则仅会按相应比例计入 PSS 值。例如,两个进程之间共享的 RAM 页会将其一半的大小分别计入这两个进程的 PSS 中。
Dalvik Heap
-
应用中的 Dalvik 分配所占用的 RAM。Pss Total 包括所有 Zygote 分配(如上述 PSS 定义中所述,通过进程之间共享的内存容量来衡量)。Private Dirty 值是仅分配给您的应用堆的实际 RAM,包含了您自己的分配和任何 Zygote 分配页,这些分配页自从 Zygote 派生您的应用进程以来已被修改。
注意:在包含 Dalvik Other 区段的更高平台版本上,Dalvik 堆的 Pss Total 和 Private Dirty 数值不包括 Dalvik 开销(例如即时编译 (JIT) 和垃圾回收记录),而更低的版本会在 Dalvik 中将其一并列出。
.so mmap 和 .dex mmap
-
映射的
.so
(原生)和.dex
(Dalvik 或 ART)代码占用的 RAM。Pss Total 值包括应用之间共享的平台代码;Private Clean
是您的应用自己的代码。通常,实际映射的内存容量要大得多。此处的 RAM 只是应用已执行的代码当前需要占用的 RAM
。不过,.so mmap
具有较大容量的私有脏 RAM,这是因为在将其加载到最终地址时对原生代码进行了修复(However, the .so mmap has a large private dirty, which is due to fix-ups to the native code when it was loaded into its final address.)。
.oat mmap
-
这是代码映像占用的 RAM 容量,根据由多个应用共用的预加载类计算。此映像在所有应用之间共享,不受特定应用影响。
.art mmap
-
这是堆映像占用的 RAM 容量,根据由多个应用共用的预加载类计算。此映像在所有应用之间共享,不受特定应用影响。尽管 ART 映像包含 Object 实例,但它不会计入您的堆占用空间。
Unknown
-
系统无法将其分类到其他更具体的一个项中的任何 RAM 页。当前,此类 RAM 页主要包含原生分配,由于地址空间布局随机化 (ASLR),工具在收集此数据时无法识别这些分配。与 Dalvik 堆相同,Unknown 的 Pss Total 考虑了与 Zygote 共享的容量,且 Private Dirty 是仅由您的应用占用的未知 RAM。
TOTAL
-
您的进程占用的按比例分摊的内存大小 (PSS) RAM 总容量,等于上述所有 PSS 字段的总和。该值表示了您的进程占用的内存容量占总体内存容量的比重,可以直接与其他进程和可用的总 RAM 进行比较。
Private Dirty
和Private Clean
合起来就是您进程中的总分配,这些分配未与其他进程共享。这些分配(尤其是 Private Dirty)的容量等于进程销毁后将释放到系统中的 RAM 容量。脏 RAM 页由于已被修改过,因此必须保留在 RAM 中(因为没有交换);干净 RAM 页是从某个持久性文件(例如正在执行的代码)映射而来的,因此如果暂时不使用,可以将其换出 RAM。
ViewRootImpl
-
您的进程中当前处于活动状态的根视图数量。每个根视图都与一个窗口关联,因此该值有助于确定与对话框或其他窗口有关的内存泄漏。
AppContexts 和 Activities
-
您的进程中当前处于活动状态的应用 Context 和 Activity 对象数量。该值可以帮助您快速确定发生泄漏的 Activity 对象,这些对象由于存在对其的静态引用(比较常见)而无法进行垃圾回收。这些对象往往关联了许多其他分配,因此是查找大型内存泄漏的理想工具。
注意:View 或 Drawable 对象也会保留对其源 Activity 的引用,因此保留 View 或 Drawable 对象也会导致您的应用泄漏 Activity。
.Heap(仅带有 -d 标志)
-
这是应用堆所占用的内存容量,其中不包括映像中的对象和大型对象空间,但包括 zygote 空间和非移动空间。
.LOS(仅带有 -d 标志)
-
这是由 ART 大型对象空间占用的 RAM 容量,其中包括 zygote 大型对象。大型对象是所有大于 12KB 的原语数组分配。
.GC(仅带有 -d 标志)
-
这是垃圾回收的开销成本。没有什么办法能够真正减少这一开销。
.JITCache(仅带有 -d 标志)
-
这是 JIT 数据和代码缓存占用的内存容量。通常情况下,该值为 0,因为所有应用都会在安装时编译。
.Zygote(仅带有 -d 标志)
-
这是 zygote 空间占用的内存容量。zygote 空间在设备启动过程创建且永远不会被分配。
.NonMoving(仅带有 -d 标志)
-
这是由 ART 非移动空间占用的 RAM 容量。非移动空间包含特殊的不可移动对象,例如字段和方法。您可以通过在应用中减少使用字段和方法来减小这部分空间。
.IndirectRef(仅带有 -d 标志)
-
这是由 ART 间接引用表占用的 RAM 容量。通常此容量较小,但如果很高,可以通过减少使用的本地和全局 JNI 引用数量来减小此容量。