news 2026/8/6 10:03:18

PSS/RSS废弃了?Android/Google主推memory cgroup(memcg)衡量和管理App内存?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PSS/RSS废弃了?Android/Google主推memory cgroup(memcg)衡量和管理App内存?

PSS/RSS废弃了?Android/Google将用memory cgroup(memcg)衡量和管理App内存?

摘要:Android系统正逐渐转向使用memory cgroup(memcg)作为应用内存管理的主要机制,而非传统的PSS/RSS指标。PSS/RSS仍用于调试(如dumpsys meminfo),但存在共享内存重复计算(RSS)、统计成本高(PSS)等问题,且无法准确反映系统内存回收收益。memcg通过内核级资源隔离和聚合统计(按UID/进程组),更贴近LMKD/OOM等系统管理逻辑,支持实时低开销监控。查看memcg数据需区分cgroup v1(/dev/memcg)或v2(/sys/fs/cgroup),结合memory.usage_in_bytesmemory.current等文件。建议内存分析时综合memcg、PSS及smaps_rollup数据,以全面评估应用内存占用。

关键词:memory cgroup, PSS/RSS, Android内存管理, LMKD, cgroup v1/v2

PSS / RSS 并不是完全“废弃不能用”了,它们仍然在 Android 调试中很常见,比如:

adb shell dumpsys meminfo <package> adb shell cat /proc/<pid>/status adb shell cat /proc/<pid>/smaps_rollup

但在更底层、更接近系统内存治理的场景里,Android / Google 越来越倾向于用memory cgroup,简称 memcg来衡量和管理应用内存。

Linux Memory Control Group / memory cgroup

1. 什么是 memory cgroup / memcg?

Linux cgroup 是一种资源隔离和统计机制。

memory cgroup 用来统计和限制某个进程组的内存使用。

Android 上每个 App 进程通常会被放进某个 cgroup,例如:

uid_10123/pid_12345

或者按 UID 聚合:

uid_10123

这样系统就可以知道:

某个 App 或某个 UID 下面的所有进程,一共占用了多少内存资源。

memcg 不只是一个“统计工具”,它还和系统内存回收、LMKD、OOM、内存压力管理等机制关系更近。

2. PSS / RSS 分别是什么?

RSS:Resident Set Size

RSS 表示进程当前驻留在物理内存中的页面总量。

可以理解为:

这个进程映射到的、当前在 RAM 里的内存页大小。

查看方式:

adb shell cat /proc/<pid>/status | grep VmRSS

或者:

adb shell cat /proc/<pid>/statm

问题是,RSS 对共享内存会重复计算

例如:

libandroid_runtime.so 被 100 个进程共享

每个进程的 RSS 都可能把这部分算进去。

所以如果把所有 App 的 RSS 加起来,结果可能远远超过真实物理内存使用量。

PSS:Proportional Set Size

PSS 是 Android 很长时间里常用的内存指标。

PSS 会把共享页面按比例分摊。

例如一个 100KB 的 so 页面被 10 个进程共享:

每个进程 PSS 只算 10KB

所以 PSS 比 RSS 更适合回答:

这个进程大概应该为多少物理内存负责?

查看方式:

adb shell dumpsys meminfo <package>

或者:

adb shell cat /proc/<pid>/smaps_rollup

里面会有:

Pss: Rss: Private_Dirty: Private_Clean: SwapPss:

3. 那为什么还要引入 memcg?

因为 PSS / RSS 都有一些天然问题,尤其是在现代 Android 系统中。

原因一:RSS 会严重重复计算共享内存

RSS 最大的问题是共享内存重复计算。

Android App 会共享很多东西:

  1. zygote 预加载类;

  2. framework 资源;

  3. shared library;

  4. mmap 文件;

  5. ashmem;

  6. graphics buffer;

  7. ART / oat / vdex 映射;

  8. WebView 相关共享资源。

如果只看 RSS,一个 App 可能看起来特别大,但里面很多其实是共享的。

所以 RSS 不适合作为 App 内存占用的标准指标。

原因二:PSS 计算成本比较高

PSS 需要遍历/proc/<pid>/smaps或内核相关页表统计。

这类统计相对昂贵。

单个进程看还好,如果系统频繁对所有进程算 PSS,就会有明显成本。

例如:

adb shell dumpsys meminfo

这个命令本身就可能比较慢,因为它要收集很多进程的 smaps 信息。

在系统内存压力管理中,系统希望有一个更低成本、更实时、更适合内核使用的指标。

memcg 就更接近内核实时记账模型。

原因三:PSS 是“比例分摊模型”,但不一定符合真实回收/杀进程收益

PSS 的逻辑是:

共享内存按使用者数量均摊。

这在统计上比较公平,但对系统回收内存来说不一定准确。

举个例子:

某个共享页面被 A、B 两个进程使用。

PSS 中 A 算一半,B 算一半。

但如果杀掉 A,这个共享页面因为 B 还在用,可能并不会释放。

所以 PSS 回答的是:

这个进程应该分摊多少内存?

但系统内存治理更关心的是:

这个 App 进程组实际给系统带来了多少内存压力?
杀掉/回收这个 cgroup,大概能释放或缓解多少压力?
哪个 UID / App 正在消耗最多内存资源?

memcg 更接近系统调度、回收、LMK 的实际模型。

原因四:PSS/RSS 主要基于进程,但 Android App 不一定只有一个进程

一个 Android 应用可能有多个进程:

com.example.app com.example.app:remote com.example.app:webview com.example.app:push com.example.app:camera

如果只看某个 pid 的 PSS/RSS,容易低估整个 App 的内存。

而 memcg 可以按 UID 或进程组聚合:

uid_10123

这样更适合描述:

这个应用整体用了多少内存。

原因五:memcg 能覆盖更多内核视角的资源

PSS/RSS 更多是进程虚拟内存映射视角。

memcg 是内核 memory controller 的记账视角,现代内核里可以统计更多类型,例如:

  1. anonymous memory;

  2. file cache;

  3. shmem;

  4. page table;

  5. kernel stack;

  6. socket memory;

  7. slab;

  8. swap;

  9. zram 相关记账;

  10. cgroup 内聚合内存。

不同 Android 版本和内核配置统计范围会有差异,但总体上 memcg 更贴近内核真实内存压力管理。

4. 所以 PSS / RSS 为什么“不够用了”?

可以简单总结成:

指标

优点

问题

RSS

获取简单,表示驻留物理内存

共享内存重复计算,容易虚高

PSS

共享内存按比例分摊,更适合人工分析

计算成本高,不够实时,和系统回收收益不完全一致

memcg

内核直接记账,适合按 App/UID 聚合,贴近 LMK/回收机制

解释起来不如 PSS 直观,不同系统版本路径和字段可能不同

所以不是 PSS/RSS “错了”,而是:

Android 系统级内存治理更需要一个低成本、实时、可聚合、和内核回收机制一致的指标。

这就是 memcg 越来越重要的原因。

5. memcg 和 PSS 的数值为什么可能不一样?

很正常。

因为它们的统计口径不同。

例如:

PSS = 进程地址空间中内存页的比例分摊 memcg = 内核 memory cgroup 对这个 cgroup 的实际记账 RSS = 当前进程 resident page 的总和

常见差异来源包括:

  1. 共享页面计算方式不同;

  2. page cache 是否计入;

  3. kernel memory 是否计入;

  4. swap/zram 是否计入;

  5. 是否按 UID 聚合;

  6. 多进程 App 是否全部计入;

  7. 图形 buffer / ashmem / dma-buf 的归属差异;

  8. Android 版本和内核版本差异。

所以可能看到:

PSS = 300MB memcg = 420MB RSS = 800MB

这不一定矛盾,只是统计口径不同。

6. Android 上怎么查看 memcg?

不同 Android 版本路径不同。最稳妥的方法是先看目标进程属于哪个 cgroup。

假设包名是:

com.example.app

先拿 pid:

adb shell pidof com.example.app

例如输出:

12345

然后看这个进程的 cgroup:

adb shell cat /proc/12345/cgroup

可能看到两类情况。

7. 情况一:cgroup v1,常见路径/dev/memcg

有些设备上会看到类似:

4:memory:/apps/uid_10123/pid_12345

或者:

memory:/apps/uid_10123/pid_12345

这表示 memory controller 的路径是:

/apps/uid_10123/pid_12345

对应到文件系统可能是:

/dev/memcg/apps/uid_10123/pid_12345

可以查看:

adb shell cat /dev/memcg/apps/uid_10123/pid_12345/memory.usage_in_bytes

这个值单位是 byte。

也可以查看详细统计:

adb shell cat /dev/memcg/apps/uid_10123/pid_12345/memory.stat

如果想看整个 UID:

adb shell cat /dev/memcg/apps/uid_10123/memory.usage_in_bytes adb shell cat /dev/memcg/apps/uid_10123/memory.stat

8. 情况二:cgroup v2,常见路径/sys/fs/cgroup

新系统上可能看到:

0::/uid_10123/pid_12345

这通常表示 unified cgroup v2。

对应路径一般类似:

/sys/fs/cgroup/uid_10123/pid_12345

查看当前内存:

adb shell cat /sys/fs/cgroup/uid_10123/pid_12345/memory.current

查看峰值,部分系统支持:

adb shell cat /sys/fs/cgroup/uid_10123/pid_12345/memory.peak

查看详细统计:

adb shell cat /sys/fs/cgroup/uid_10123/pid_12345/memory.stat

查看整个 UID:

adb shell cat /sys/fs/cgroup/uid_10123/memory.current adb shell cat /sys/fs/cgroup/uid_10123/memory.stat

9. 推荐的通用查看步骤

可以按这个流程查。

第一步:找到 pid

adb shell pidof -s com.example.app

假设得到:

12345

第二步:查看 cgroup 信息

adb shell cat /proc/12345/cgroup

输出如果类似:

4:memory:/apps/uid_10123/pid_12345

说明大概率是 cgroup v1 memory。

如果类似:

0::/uid_10123/pid_12345

说明大概率是 cgroup v2。

第三步:查看挂载点

adb shell cat /proc/mounts | grep cgroup

或者:

adb shell cat /proc/mounts | grep memcg

如果看到:

/dev/memcg cgroup ...

/dev/memcg

如果看到:

/sys/fs/cgroup cgroup2 ...

/sys/fs/cgroup

第四步:读取内存值

cgroup v1:

adb shell cat /dev/memcg/apps/uid_10123/pid_12345/memory.usage_in_bytes adb shell cat /dev/memcg/apps/uid_10123/pid_12345/memory.stat

cgroup v2:

adb shell cat /sys/fs/cgroup/uid_10123/pid_12345/memory.current adb shell cat /sys/fs/cgroup/uid_10123/pid_12345/memory.stat

10. 如何把 byte 转成 MB?

比如:

adb shell cat /sys/fs/cgroup/uid_10123/pid_12345/memory.current

输出:

268435456

换算:

268435456 / 1024 / 1024 = 256 MB

可以直接用 shell:

adb shell 'v=$(cat /sys/fs/cgroup/uid_10123/pid_12345/memory.current); echo $((v/1024/1024)) MB'

11.memory.stat里面常见字段怎么看?

cgroup v2 的memory.stat常见字段可能有:

anon file kernel kernel_stack pagetables percpu sock shmem file_mapped file_dirty file_writeback swapcached anon_thp file_thp shmem_thp inactive_anon active_anon inactive_file active_file slab_reclaimable slab_unreclaimable

大致可以这样理解:

字段

含义

anon

匿名内存,例如 Java/Kotlin heap、native heap 等

file

文件页缓存、mmap 文件等

shmem

shared memory

kernel

内核侧记账内存,部分系统有

pagetables

页表内存

kernel_stack

内核栈

sock

socket buffer

active_anon

/

inactive_anon

活跃/非活跃匿名页

active_file

/

inactive_file

活跃/非活跃文件页

cgroup v1 的memory.stat字段可能是:

cache rss rss_huge shmem mapped_file dirty writeback swap pgpgin pgpgout total_cache total_rss total_shmem total_mapped_file

字段名字和含义会随内核版本、Android 版本变化。

12. 和dumpsys meminfo对比怎么看?

可以同时看:

adb shell dumpsys meminfo com.example.app

以及:

adb shell cat /proc/<pid>/smaps_rollup

再看 memcg:

adb shell cat /sys/fs/cgroup/uid_xxxxx/pid_xxxxx/memory.current

或者:

adb shell cat /dev/memcg/apps/uid_xxxxx/pid_xxxxx/memory.usage_in_bytes

会发现它们通常不会完全一致。

这是正常的。

建议这样使用:

场景

建议看什么

分析 Java heap / Native heap / Graphics / Code 等分类

dumpsys meminfo

看进程 PSS/RSS/SwapPSS

/proc/<pid>/smaps_rollup

看系统对 App/UID 的内存记账

memcg

看是否接近 LMK / 系统内存压力

memcg + lmkd log + PSI

看 Java 对象泄漏

Android Studio Profiler / heap dump

看 native 泄漏

heapprofd / malloc debug / perfetto

13. memcg 能否替代 PSS?

不能简单说完全替代。

更准确说:

memcg 更适合系统级内存治理和 App 整体内存归因;PSS 更适合传统应用内存分析和跨进程共享内存的比例分摊视角。

比如要回答:

App 为什么被 LMK 杀了?

应该重点看:

memcg usage PSI lmkd log oom_score_adj 系统 available memory

而不是只看 PSS。

但要回答:

我的 Activity 页面打开后多占了多少 Java heap / native heap / graphics?

dumpsys meminfo和 PSS 分类仍然很有价值。

14. 为什么 Google / Android 会更重视 memcg?

核心原因可以概括为一句话:

Android 的内存压力、回收、杀进程决策越来越依赖内核 cgroup 体系,memcg 是更贴近系统实际资源管理的口径。

具体包括:

  1. 可以按 UID / App 聚合;

  2. 可以低成本读取;

  3. 和 LMKD、OOM、内存压力机制更一致;

  4. 更适合多进程 App;

  5. 更适合现代 Android 的图形、WebView、zygote、mmap、zram 场景;

  6. 不需要频繁扫描 smaps;

  7. 可以和 PSI、cgroup reclaim 等机制联动。

15. 一个实际排查建议

如果在分析某个 App 的“真实内存占用”,建议同时采集这几类数据:

# 1. pid adb shell pidof com.example.app # 2. meminfo adb shell dumpsys meminfo com.example.app # 3. smaps_rollup adb shell cat /proc/<pid>/smaps_rollup # 4. cgroup adb shell cat /proc/<pid>/cgroup # 5. memcg usage/stat adb shell cat /sys/fs/cgroup/uid_xxxxx/pid_xxxxx/memory.current adb shell cat /sys/fs/cgroup/uid_xxxxx/pid_xxxxx/memory.stat

如果是 cgroup v1,则换成:

adb shell cat /dev/memcg/apps/uid_xxxxx/pid_xxxxx/memory.usage_in_bytes adb shell cat /dev/memcg/apps/uid_xxxxx/pid_xxxxx/memory.stat

总结

PSS / RSS 不是完全废弃,而是它们在现代 Android 系统内存治理中有局限:

  1. RSS 对共享内存重复计算;

  2. PSS 计算成本高;

  3. PSS 是比例分摊模型,不完全等价于系统回收收益;

  4. 多进程 App 下单 pid PSS/RSS 容易低估整体;

  5. 它们和 LMKD / 内核回收 / cgroup 机制不完全一致。

memcg 的优势是:

  1. 内核直接记账;

  2. 可按进程组/UID/App 聚合;

  3. 更低成本;

  4. 更接近系统内存压力和 LMK 决策;

  5. 更符合现代 Android 的资源治理模型。

查看方式主要是:

adb shell cat /proc/<pid>/cgroup

然后根据系统是 cgroup v1 还是 v2,读取:

/dev/memcg/.../memory.usage_in_bytes

或:

/sys/fs/cgroup/.../memory.current
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/6 10:02:30

嵌入式 C 语言宏的高级编程技巧与实战

《 嵌入式 C 语言宏的高级编程技巧与实战》大家好&#xff0c;我是杂烩君。我们一起来看看libevhtp这个高性能HTTP服务器库中&#xff0c;用到的宏高级技巧。1. 分支预测优化现代CPU都有分支预测器&#xff0c;一旦预测错误&#xff0c;流水线得全部冲掉&#xff0c;性能瞬间暴…

作者头像 李华
网站建设 2026/8/6 10:02:00

Claude Code AI编程助手:安装配置与核心命令详解

1. Claude Code核心定位解析 作为7D-AI系列中的明星产品&#xff0c;Claude Code本质上是一个深度集成在开发环境中的AI编程助手。不同于传统代码补全工具&#xff0c;它通过自然语言交互理解开发者意图&#xff0c;能实现从单行代码建议到完整功能模块生成的跨越式辅助。我在三…

作者头像 李华
网站建设 2026/8/6 9:59:34

分析代码硬编码与LLM判断及SOP执行

根据对项目代码和配置文件的全面分析&#xff0c;我将从以下三个方面回答你的问题&#xff1a;一、硬编码规则&#xff08;Java代码中直接写死的逻辑&#xff09;以下规则在代码中明确硬编码&#xff0c;不依赖 LLM 或配置文件动态调整&#xff1a;1. 强制状态推进规则&#xf…

作者头像 李华
网站建设 2026/8/6 9:58:56

深入解析MAI-UI:基于多模态大模型的GUI智能体架构与工程实践

1. 从“智能体”到“界面”&#xff1a;MAI-UI的定位与价值最近在关注GUI-Agent&#xff08;图形用户界面智能体&#xff09;这个领域&#xff0c;发现阿里通义实验室开源的MAI-UI项目热度很高。作为一个长期和界面自动化、RPA&#xff08;机器人流程自动化&#xff09;打交道的…

作者头像 李华
网站建设 2026/8/6 9:56:40

3分钟配置:PotPlayer百度翻译插件全攻略

3分钟配置&#xff1a;PotPlayer百度翻译插件全攻略 【免费下载链接】PotPlayer_Subtitle_Translate_Baidu PotPlayer 字幕在线翻译插件 - 百度平台 项目地址: https://gitcode.com/gh_mirrors/po/PotPlayer_Subtitle_Translate_Baidu 还在为看外语电影时听不懂对话而苦…

作者头像 李华