我正在尝试设置一些监视以查看服务何时使用过多内存。可以从两个地方读取内存使用情况:
- 用于
/proc/<pid>/status
pid,或 - 用于运行它的
/sys/fs/cgroup/<group-id>/memory.stat
对照组。
该服务由 systemd 启动,因此它有自己的控制组,并且因为它有时会启动我需要包含在统计信息中的子进程,并且因为路径在重新启动时是恒定的,所以控制组统计信息更合适。
不幸的是,数字似乎不匹配。这是没有子进程运行时的值示例(命令与执行完全相同,除了服务名称,结果与获取完全相同,除了与内存相关的项目被删除):
# cat /sys/fs/cgroup/system.slice/some.service/memory.stat /proc/$(cat /sys/fs/cgroup/system.slice/some.service/cgroup.procs)/status
anon 5873664
file 2408448
kernel_stack 491520
slab 962560
sock 0
shmem 61440
file_mapped 405504
file_dirty 0
file_writeback 0
inactive_anon 0
active_anon 5853184
inactive_file 1916928
active_file 360448
unevictable 0
slab_reclaimable 270336
slab_unreclaimable 692224
pgfault 60258
pgmajfault 99
pgrefill 0
pgscan 0
pgsteal 0
pgactivate 0
pgdeactivate 0
pglazyfree 0
pglazyfreed 0
workingset_refault 0
workingset_activate 0
workingset_nodereclaim 0
…
VmPeak: 494812 kB
VmSize: 494164 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 25836 kB
VmRSS: 25484 kB
RssAnon: 5468 kB
RssFile: 20016 kB
RssShmem: 0 kB
VmData: 464776 kB
VmStk: 132 kB
VmExe: 180 kB
VmLib: 23940 kB
VmPTE: 156 kB
VmSwap: 0 kB
voluntary_ctxt_switches: 9
nonvoluntary_ctxt_switches: 620
我会认为过程统计中的适当值是VmRSS
(= RssAnon
+ RssFile
+ RssShmem
)。但是,虽然我认为anon
小组应该RssAnon
属于过程,file
小组应该RssFile
属于过程,但它们并不匹配。虽然anon
是 5736 KB,RssAnon
但只有 5468 KB,而对于文件来说差异更大,file
只有 2352 KB,但RssFile
为 20016 KB,几乎是数量级的差异。
还有memory.current
一个值与anon
+ file
+ kernel_stack
+ slab
+ sock
+大致匹配的文件shmem
,但我在进程状态中看不到任何匹配值。
那么为什么这些数字如此不同,哪些数字更能说明应用程序对系统施加的内存压力呢?
注意:在内核 4.19.72(稍微陈旧的嵌入式 BSP)上使用 cgroup2。
来自控制组 v2指南:
file
因此,我们将从in cgroups 和RssFile
in之间的区别开始/proc/<pid>/status
:该进程可能已经打开了 20016 KB 的文件,但是这些文件页面可能之前已经存在于内存缓存中,因为其他进程已经打开了它们,并且它们各自的 cgroup 对它们收费。因此,在这 20016 KB 中,只有 2352 KB 由 cgroup 收费,其余的属于其他 cgroup(以及之前加载这些文件的进程)。
anon
关于in cgroups 和RssAnon
in之间的区别/proc/<pid>/status
,我没有任何好的解释。关于
memory.current
,据我所知,所有内核内部结构(如kernel_stack
和slab
)仅在 cgroup 中可见,并且您看不到这些数字的每个进程的统计信息,因为/proc/<pid>/status
仅显示用户空间内存信息。