mem cgroup-2-memcg文件节点介绍
基于kernel-6.1.114
一、相关文件节点
1. /dev/memcg
/dev/memcg # ls -l drwxr-xr-x 2 system system 0 2010-01-01 08:00 apps //子目录 -rw-r--r-- 1 root root 0 2010-01-01 09:16 cgroup.clone_children //0 --w--w--w- 1 root root 0 2010-01-01 09:16 cgroup.event_control -rw-r--r-- 1 root root 0 2010-01-01 09:16 cgroup.procs //大量 -r--r--r-- 1 root root 0 2010-01-01 09:16 cgroup.sane_behavior //0 -rw-r--r-- 1 root root 0 2010-01-01 09:16 memory.failcnt //0 --w------- 1 root root 0 2010-01-01 09:16 memory.force_empty -rw-r--r-- 1 root root 0 2010-01-01 09:16 memory.kmem.failcnt //0 -rw-r--r-- 1 root root 0 2010-01-01 09:16 memory.kmem.limit_in_bytes //9223372036854771712 = 0x7FFFFFFFFFFFFFF0 -rw-r--r-- 1 root root 0 2010-01-01 09:16 memory.kmem.max_usage_in_bytes //0 -r--r--r-- 1 root root 0 2010-01-01 09:16 memory.kmem.slabinfo //空 -rw-r--r-- 1 root root 0 2010-01-01 09:16 memory.kmem.tcp.failcnt //0 -rw-r--r-- 1 root root 0 2010-01-01 09:16 memory.kmem.tcp.limit_in_bytes //9223372036854771712 -rw-r--r-- 1 root root 0 2010-01-01 09:16 memory.kmem.tcp.max_usage_in_bytes //0 -r--r--r-- 1 root root 0 2010-01-01 09:16 memory.kmem.tcp.usage_in_bytes //0 -r--r--r-- 1 root root 0 2010-01-01 09:16 memory.kmem.usage_in_bytes //0 -rw-r--r-- 1 root root 0 2010-01-01 09:16 memory.limit_in_bytes //9223372036854771712 -rw-r--r-- 1 root root 0 2010-01-01 09:16 memory.max_usage_in_bytes //0 -rw-r--r-- 1 root root 0 2010-01-01 09:16 memory.memsw.failcnt //0 -rw-r--r-- 1 root root 0 2010-01-01 09:16 memory.memsw.limit_in_bytes //9223372036854771712 -rw-r--r-- 1 root root 0 2010-01-01 09:16 memory.memsw.max_usage_in_bytes //0 -r--r--r-- 1 root root 0 2010-01-01 09:16 memory.memsw.usage_in_bytes //9677598720 #### -rw-r--r-- 1 root root 0 2010-01-01 09:16 memory.move_charge_at_immigrate //0 -rw-r--r-- 1 root root 0 2010-01-01 09:16 memory.oom_control //oom_kill_disable 0, under_oom 0, oom_kill 0 ----r----- 1 root system 0 2010-01-01 08:00 memory.pressure_level //cat报错"cat: memory.pressure_level: Invalid argument" -rw-r--r-- 1 root root 0 2010-01-01 09:16 memory.soft_limit_in_bytes //9223372036854771712 -r--r--r-- 1 root root 0 2010-01-01 09:16 memory.stat //见下文cat -rw-r--r-- 1 root root 0 2010-01-01 09:16 memory.swappiness //100 -r--r--r-- 1 root root 0 2010-01-01 09:16 memory.usage_in_bytes //7395565568 #### -rw-r--r-- 1 root root 0 2010-01-01 09:16 memory.use_hierarchy //1 -rw-r--r-- 1 root root 0 2010-01-01 09:16 notify_on_release //0 -rw-r--r-- 1 root root 0 2010-01-01 09:16 release_agent //空 dr-xr-x--- 2 system system 0 2010-01-01 08:00 system //子目录 -rw-r--r-- 1 root root 0 2010-01-01 09:16 tasks //大量
memory.stat 文件内容:
/dev/memcg # cat memory.stat cache 3447140352 rss 3951267840 rss_huge 0 shmem 35467264 mapped_file 1750802432 dirty 483328 writeback 0 workingset_refault_anon 76330 workingset_refault_file 212187 swap 2282438656 pgpgin 16405153 pgpgout 14612101 pgfault 19587646 pgmajfault 90014 inactive_anon 769310720 active_anon 3207593984 inactive_file 1358106624 active_file 2060623872 unevictable 5656576 hierarchical_memory_limit 9223372036854771712 hierarchical_memsw_limit 9223372036854771712 total_cache 3447140352 total_rss 3951267840 total_rss_huge 0 total_shmem 35467264 total_mapped_file 1750802432 total_dirty 483328 total_writeback 0 total_workingset_refault_anon 76330 total_workingset_refault_file 212187 total_swap 2282438656 total_pgpgin 16405153 total_pgpgout 14612101 total_pgfault 19587646 //和 /proc/vmstat 的 pgfault 一致 total_pgmajfault 90014 total_inactive_anon 769310720 total_active_anon 3207593984 total_inactive_file 1358106624 total_active_file 2060623872 total_unevictable 5656576
2. /dev/memcg/apps 和 /dev/memcg/system
实际 cat 看,apps 目录和 system 目录打印出来的内容都一样,这里以 apps 目录为例:
/dev/memcg # ls apps/ -l -rw-r--r-- 1 root root 0 2010-01-01 09:24 cgroup.clone_children //0 --w--w--w- 1 root root 0 2010-01-01 09:24 cgroup.event_control -rw-r--r-- 1 root root 0 2010-01-01 09:24 cgroup.procs //空 -rw-r--r-- 1 root root 0 2010-01-01 09:24 memory.failcnt //0 --w------- 1 root root 0 2010-01-01 09:24 memory.force_empty -rw-r--r-- 1 root root 0 2010-01-01 09:24 memory.kmem.failcnt //0 -rw-r--r-- 1 root root 0 2010-01-01 09:24 memory.kmem.limit_in_bytes //9223372036854771712 = 0x7FFFFFFFFFFFFFF0 -rw-r--r-- 1 root root 0 2010-01-01 09:24 memory.kmem.max_usage_in_bytes //0 -r--r--r-- 1 root root 0 2010-01-01 09:24 memory.kmem.slabinfo //空 -rw-r--r-- 1 root root 0 2010-01-01 09:24 memory.kmem.tcp.failcnt //0 -rw-r--r-- 1 root root 0 2010-01-01 09:24 memory.kmem.tcp.limit_in_bytes //9223372036854771712 -rw-r--r-- 1 root root 0 2010-01-01 09:24 memory.kmem.tcp.max_usage_in_bytes //0 -r--r--r-- 1 root root 0 2010-01-01 09:24 memory.kmem.tcp.usage_in_bytes //0 -r--r--r-- 1 root root 0 2010-01-01 09:24 memory.kmem.usage_in_bytes //0 -rw-r--r-- 1 root root 0 2010-01-01 09:24 memory.limit_in_bytes //9223372036854771712 -rw-r--r-- 1 root root 0 2010-01-01 09:24 memory.max_usage_in_bytes //0 -rw-r--r-- 1 root root 0 2010-01-01 09:24 memory.memsw.failcnt //0 -rw-r--r-- 1 root root 0 2010-01-01 09:24 memory.memsw.limit_in_bytes //9223372036854771712 -rw-r--r-- 1 root root 0 2010-01-01 09:24 memory.memsw.max_usage_in_bytes //0 -r--r--r-- 1 root root 0 2010-01-01 09:24 memory.memsw.usage_in_bytes //0 -rw-r--r-- 1 root root 0 2010-01-01 09:24 memory.move_charge_at_immigrate //0 -rw-r--r-- 1 root root 0 2010-01-01 09:24 memory.oom_control //oom_kill_disable 0, under_oom 0, oom_kill 0 ---------- 1 root root 0 2010-01-01 09:24 memory.pressure_level //子目录的既不能读,又不能写 -rw-r--r-- 1 root root 0 2010-01-01 09:24 memory.soft_limit_in_bytes //9223372036854771712 -r--r--r-- 1 root root 0 2010-01-01 09:24 memory.stat //见下文cat -rw-r--r-- 1 root root 0 2010-01-01 09:24 memory.swappiness //60 -r--r--r-- 1 root root 0 2010-01-01 09:24 memory.usage_in_bytes //0 -rw-r--r-- 1 root root 0 2010-01-01 09:24 memory.use_hierarchy //1 -rw-r--r-- 1 root root 0 2010-01-01 09:24 notify_on_release //0 -rw-r--r-- 1 root root 0 2010-01-01 09:24 tasks //空
memory.stat 文件节点内容:
/dev/memcg/apps # cat memory.stat cache 0 rss 0 rss_huge 0 shmem 0 mapped_file 0 dirty 0 writeback 0 workingset_refault_anon 0 workingset_refault_file 0 swap 0 pgpgin 0 pgpgout 0 pgfault 0 pgmajfault 0 inactive_anon 0 active_anon 0 inactive_file 0 active_file 0 unevictable 0 hierarchical_memory_limit 9223372036854771712 hierarchical_memsw_limit 9223372036854771712 total_cache 0 total_rss 0 total_rss_huge 0 total_shmem 0 total_mapped_file 0 total_dirty 0 total_writeback 0 total_workingset_refault_anon 0 total_workingset_refault_file 0 total_swap 0 total_pgpgin 0 total_pgpgout 0 total_pgfault 0 total_pgmajfault 0 total_inactive_anon 0 total_active_anon 0 total_inactive_file 0 total_active_file 0 total_unevictable 0
二、文件节点介绍
1. 子组的文件节点
1.1 apps
含义:子内存控制组目录,通常放应用进程。作用:在这个目录下再有一套同名 memory.* 文件,代表该子组的独立内存控制状态。
1.2 system
含义:另一个子组,通常放系统服务进程。作用同上,和 apps 隔离统计与限制。
2. 通用控制文件
2.1 cgroup.clone_children
含义:历史兼容开关。在 memcg 上通常没有实际业务价值,更多是旧接口保留。很多系统里可忽略。
2.2 cgroup.event_control
含义:事件订阅入口(写接口)。把 eventfd 和某个“事件源文件”绑定,例如 memory.oom_control、memory.pressure_level。
典型用途:用户态守护进程通过 eventfd 收到 OOM 或压力事件通知。
注意:这是配置接口,本身不直接返回“状态值”。
2.3 cgroup.procs
含义:该 cgroup 中的进程(TGID)列表。读:返回进程号列表。写:写入一个 PID,把该进程(通常线程组整体)迁入当前 cgroup。
2.4 tasks
含义:该 cgroup 中的线程(TID)列表。读:返回线程号列表。写:写入一个 TID,把该线程迁入当前 cgroup。
与 cgroup.procs 区别:procs 偏进程粒度,tasks 偏线程粒度。
2.5 notify_on_release
含义:释放通知开关。写 1:当该 cgroup 变空且被释放时,可触发 release_agent 机制。现代系统较少使用。
2.5 release_agent
含义:release 回调程序路径。只有根组有。配合 notify_on_release 使用,cgroup 释放时由内核触发该程序。
安全敏感,生产环境通常禁用或不用。
2.6 cgroup.sane_behavior
含义:历史“层级行为”兼容标志。只有根组有。现代内核上基本是遗留接口,通常不作为调优项使用。
3. memory 主控制文件
3.1 memory.usage_in_bytes
含义:当前已计费内存使用量(主要是用户内存页相关)。
说明:是动态值,瞬时抖动正常。
3.2 memory.max_usage_in_bytes
含义:历史峰值使用量。写 0:重置峰值计数。
3.3 memory.limit_in_bytes
含义:硬限制(hard limit)。达到后会触发回收,仍无法满足时可能触发 memcg OOM。常见写法:写具体字节数;“无限制”常用非常大值(不同内核表现略有差异)。
3.4 memory.soft_limit_in_bytes
含义:软限制(best effort)。不是硬约束,只在全局内存紧张时作为回收优先级参考。
3.5 memory.failcnt
含义:命中 memory.limit_in_bytes 失败次数累计。写 0:清零。
3.6 memory.stat
含义:详细分项统计。
常见字段:rss、cache、mapped_file、pgfault、pgmajfault、inactive_anon、active_file 等。
用途:定位“谁在吃内存”和回收行为分析。
3.7 memory.swappiness
含义:该 cgroup 的 swap 倾向。常见范围:0 到 100。0 倾向少换出匿名页,100 倾向积极换出匿名页。
3.8 memory.force_empty
含义:强制回收该 cgroup 可回收页面(写触发)。常用于删除 cgroup 前尽量清空占用。注意:不是“绝对清空”,不可回收页、被引用页、pin 住页可能仍在。
3.9 memory.use_hierarchy
含义:是否按层级统计/限制。v1 老内核可配;新一些内核往往固定层级行为,写入可能被忽略或限制。在 Android 旧栈里常见为 1。
3.10 memory.move_charge_at_immigrate
含义:任务迁移时,是否连带迁移历史页面 charge。0:不迁移历史 charge。非 0:按位掩码迁移(不同内核位定义有差异,常见是匿名页/文件页位)。
用途:任务从组 A 移到组 B 后,让账单也跟着迁。
4. memory + swap(memsw)控制
4.1 memory.memsw.usage_in_bytes
含义:当前 memory + swap 合计使用量。
4.2 memory.memsw.max_usage_in_bytes
含义:history 峰值(memory + swap)。写 0:清零峰值。
4.3 memory.memsw.limit_in_bytes
含义:memory + swap 总硬限制。如果设置了 memory.limit_in_bytes 和 memsw.limit_in_bytes,两者共同生效。
4.4 memory.memsw.failcnt
含义:命中 memsw 限制失败计数。写 0:清零。
注意: memsw 依赖内核配置和启动参数(如 swapaccount)。某些 Android 设备虽然文件存在,但 swap 实际没开或策略受限,效果会打折。
5. kmem(内核内存)控制
5.1 memory.kmem.usage_in_bytes
含义:该 cgroup 的内核内存计费使用量。
5.2 memory.kmem.max_usage_in_bytes
含义:kmem 峰值。写 0 清零峰值。
5.3 memory.kmem.limit_in_bytes
含义:kmem 硬限制。老特性,现代内核很多场景已弱化或被统一内存计费替代。
5.4 memory.kmem.failcnt
含义:命中 kmem limit 的失败计数。写 0 清零。
5.5 memory.kmem.slabinfo
含义:按 slab 缓存维度的 memcg 统计。用于排查 slab 泄漏或某类内核对象异常膨胀。
注意:读取开销可能较大。
6. kmem.tcp(TCP 内核缓冲)控制
6.1 memory.kmem.tcp.usage_in_bytes
含义:TCP 相关内核内存使用量(skb、socket buffer 等)。
6.2 memory.kmem.tcp.max_usage_in_bytes
含义:TCP kmem 峰值。写 0 清零峰值。
6.3 memory.kmem.tcp.limit_in_bytes
含义:TCP kmem 硬限制。
6.4 memory.kmem.tcp.failcnt
含义:命中 TCP kmem limit 失败次数。写 0 清零。
7. OOM与压力通知
7.1 memory.oom_control
含义:memcg OOM 控制与状态。
常见字段:oom_kill_disable、under_oom、oom_kill。
用途:查看该组是否发生过/正在发生 OOM,以及是否禁用 OOM kill。还可配合 cgroup.event_control 做事件通知。
7.2 memory.pressure_level
含义:内存压力事件源(低/中/高压力)。常见不是直接读文本,而是配合 cgroup.event_control + eventfd 订阅事件。你看到权限是 "----r-----" 且属组 system,说明通常只给特定系统服务读取。只有根组的有读权限,但是 cat 依然报 "Invalid argument"。
三、实战上最常用文件
调限制:memory.limit_in_bytes、memory.soft_limit_in_bytes、memory.swappiness。
看当前和峰值:memory.usage_in_bytes、memory.max_usage_in_bytes。
看是否撞线:memory.failcnt、memory.oom_control。
深挖原因:memory.stat、memory.kmem.slabinfo。
迁移任务:cgroup.procs 或 tasks。
posted on 2026-07-31 16:59 Hello-World3 阅读(8) 评论(0) 收藏 举报
浙公网安备 33010602011771号