内存cgroup与进程RSS内存占用差异过大的原因咨询
我有一个仅包含1个进程的memory cgroup,通过memory.stat查看该cgroup的RSS内存占用为990MB,但通过/proc/[pid]/status查看该进程的RSS内存仅为165MB,二者差异巨大。相关信息如下:
相关环境信息
cgroup中的唯一进程PID
$ cat /sys/fs/cgroup/memory/karim/master/cgroup.procs 3744924
cgroup的内存限制
$ cat /sys/fs/cgroup/memory/karim/master/memory.limit_in_bytes 7340032000
cgroup的RSS内存占用
$ cat /sys/fs/cgroup/memory/karim/master/memory.stat cache 5990449152 rss 990224384 rss_huge 0 shmem 0 mapped_file 13516800 dirty 1081344 writeback 270336 pgpgin 4195191 pgpgout 2490628 pgfault 5264589 pgmajfault 0 inactive_anon 0 active_anon 990240768 inactive_file 5862830080 active_file 127021056 unevictable 0 hierarchical_memory_limit 7340032000 total_cache 5990449152 total_rss 990224384 total_rss_huge 0 total_shmem 0 total_mapped_file 13516800 total_dirty 1081344 total_writeback 270336 total_pgpgin 4195191 total_pgpgout 2490628 total_pgfault 5264589 total_pgmajfault 0 total_inactive_anon 0 total_active_anon 990240768 total_inactive_file 5862830080 total_active_file 127021056 total_unevictable 0
进程的RSS内存占用
$ cat /proc/3744924/status Name: [main] /h Umask: 0002 State: S (sleeping) Tgid: 3744924 Ngid: 0 Pid: 3744924 PPid: 3744912 TracerPid: 0 Uid: 1000 1000 1000 1000 Gid: 1001 1001 1001 1001 FDSize: 256 Groups: 1000 1001 NStgid: 3744924 NSpid: 3744924 NSpgid: 3744912 NSsid: 45028 VmPeak: 2149068 kB VmSize: 2088876 kB VmLck: 0 kB VmPin: 0 kB VmHWM: 245352 kB VmRSS: 198964 kB RssAnon: 165248 kB RssFile: 33660 kB RssShmem: 56 kB VmData: 575400 kB VmStk: 132 kB VmExe: 3048 kB VmLib: 19180 kB VmPTE: 1152 kB VmSwap: 0 kB HugetlbPages: 0 kB CoreDumping: 0 THP_enabled: 1 Threads: 17 SigQ: 0/241014 SigPnd: 0000000000000000 ShdPnd: 0000000000000000 SigBlk: 0000000000000000 SigIgn: 0000000001001000 SigCgt: 0000000180000002 CapInh: 0000000000000000 CapPrm: 0000000000000000 CapEff: 0000000000000000 CapBnd: 0000003fffffffff CapAmb: 0000000000000000 NoNewPrivs: 0 Seccomp: 0 Speculation_Store_Bypass: thread vulnerable Cpus_allowed: fff Cpus_allowed_list: 0-11 Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001 Mems_allowed_list: 0 voluntary_ctxt_switches: 94902 nonvoluntary_ctxt_switches: 1903
差异原因分析
造成二者RSS统计差异的核心原因是cgroup与进程的内存统计范围、归属规则不同,具体可能的情况如下:
1. cgroup残留未回收内存页
该cgroup可能之前运行过占用大量内存的进程,进程退出后,对应的内存页仍驻留在系统内存中(系统内存充足时,内核不会主动回收这些页)。由于这些页的归属权仍属于该cgroup,直到被重新分配给其他cgroup的进程或被内核回收,因此会被计入cgroup的rss统计,但当前进程并未使用这些内存,所以不会出现在进程的VmRSS中。
从进程的VmHWM(RSS峰值约239MB)远小于cgroup的990MB RSS可以佐证这一点:当前进程从未占用过如此大的内存,cgroup的高RSS更可能是历史进程遗留的内存页。
2. 内核内存统计范围差异
cgroup的rss统计包含了内核为该cgroup内进程分配的内存,比如线程的内核栈、内核slab分配的内存等;而/proc/[pid]/status中的VmRSS仅统计用户态的内存占用(匿名页、文件映射页、共享库页等),这部分内核内存不会被进程RSS统计,导致cgroup的RSS数值更高。
3. 共享内存的归属统计差异
如果进程创建了匿名共享内存(如mmap(MAP_ANONYMOUS|MAP_SHARED)),即使其他进程不在该cgroup中,只要共享内存是由该cgroup内的进程创建,对应的内存页会被计入cgroup的rss;但进程的VmRSS仅统计自己实际使用的共享内存部分。不过从memory.stat的shmem值为0来看,这种情况可能性极低。
内容的提问来源于stack exchange,提问作者Karim Valiev

