我编写了一个测试程序来帮助我理解不同内存实用程序的输出字段,例如 free,ps,top,/proc/$pid/status,/proc/$pid/smaps,/proc/$pid/statm 等。问题终于出现了,我无法理解:
问题:/proc/$pid/status 的 vmRss 字段是不一样与 /proc/$pid/smaps 计算出的值(通过将所有 Rss 字段相加)。
前一个值应该是“ps”命令的RSS输出的来源,而后一个值应该是“pmap -x”命令的RSS输出的来源。
我编写的测试程序是创建 20 个具有相同过程的线程,其中每个线程调用 malloc(4*1024) 256 次,导致每个线程占用内存 1MB,因此 1MB/线程 * 20 个线程 = 总共 20MB。
基于此程序,/proc/$pid/status 中 VmRSS 的输出为
VmRSS: 16468 kB
与 ps 的输出对齐
8941 0.0 0.1 4102600 16468 pts/22 Sl+ 10:07 0:00 ./a.out
而 /proc/8941/smaps 和 pmap -x 8941 的输出相加为:
$ cat /proc/8941/smaps | grep Rss | awk '{print $2}' | awk '{s+=$1} END {printf "%.0f\n", s}' /dev/stdin
22536
$ pmap -x 8941 | tail -n 1
total kB 4102604 22536 20992
free 命令的输出让我确信我的程序确实消耗了 20+MB 内存,因此“ps”和“/proc/$pid/status”的 RSS 值对我来说没有意义。
有人能解释发生了什么事吗?提前致谢。
答案1
请参阅 Linux 手册页项目:https://www.kernel.org/doc/man-pages/。他们可以解释您所看到的情况。
截至撰写本文时(版本 5.13),过程(5)说 /proc/[pid]/status 中的 VmRSS 不准确。
VmRSS 驻留集大小。请注意,此处的值是 RssAnon、RssFile 和 RssShmem 的总和。该值不准确;请参阅上面的 /proc/[pid]/statm。
proc(5) 表示 RssAnon 和 RssFile 不准确,因此 VmRSS 一定不准确。
要获得准确的值,您应该参考 /proc/[pid]/smaps (手册页在 /proc/[pid]/statm 下如此说明)。
和,附注(1)说
SIZE 和 RSS 字段不计算进程的某些部分,包括页表、内核堆栈、struct thread_info 和 struct task_struct。通常至少有 20 KiB 的内存始终驻留。 SIZE 是进程的虚拟大小(代码+数据+堆栈)。
答案2
仅仅分配内存是不够的,尝试使用该内存,尝试在应用程序中用一些值填充它,VmRSS 将会增长。