将虚拟内存大小与驻留大小进行比较

我遇到了这个stackoverflowpost:

https://stackoverflow.com/questions/10400751/how-do-vmrss-and-resident-set-size-match

答案正确表明如下:

“因此,VSS应该大于RSS。如果它们接近相等,那意味着你的进程可以舒适地放在内存中。如果VSS更大,那意味着没有足够的内存,部分内存必须被换出到磁盘(即,由于竞争过程等)。“

这句话让我很困惑,因为当我检查我的系统时,我注意到以下情况。

首先,我注意到我有很多空闲记忆:

$ cat /proc/meminfo MemTotal: 6113156 kB MemFree: 3668992 kB 

这意味着我有3.5千兆字节的纯内存(没有交换,没有磁盘等)

但是,当我看到我生成的apache2子进程时,我惊讶地发现:

 $ ps aux | grep apache2 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1130 0.0 0.1 149080 10600 ? Ss Jul11 0:03 /usr/sbin/apache2 -k start www-data 23211 0.0 0.3 163408 23784 ? S 10:34 0:03 /usr/sbin/apache2 -k start www-data 23215 0.0 0.4 164436 24832 ? S 10:34 0:02 /usr/sbin/apache2 -k start www-data 23287 0.0 0.3 163608 23992 ? S 10:36 0:02 /usr/sbin/apache2 -k start www-data 23351 0.0 0.3 163660 24064 ? S 10:40 0:01 /usr/sbin/apache2 -k start www-data 23440 0.0 0.3 161580 23588 ? S 10:46 0:00 /usr/sbin/apache2 -k start www-data 24393 0.0 0.3 163620 23496 ? S 11:32 0:00 /usr/sbin/apache2 -k start www-data 25377 0.0 0.2 150656 12316 ? S 12:20 0:00 /usr/sbin/apache2 -k start www-data 25378 0.0 0.3 158224 18400 ? S 12:20 0:00 /usr/sbin/apache2 -k start www-data 27038 0.0 0.1 149360 7816 ? S 13:01 0:00 /usr/sbin/apache2 -k start www-data 27041 0.0 0.1 149368 7660 ? S 13:01 0:00 /usr/sbin/apache2 -k start 1000 27124 0.0 0.0 8112 900 pts/0 S+ 13:04 0:00 grep apache2 

(注意grep删除列标题,所以我人为地添加它们)

看看与常驻内存相比有多大的虚拟内存。 我的意思是,例如,对于apache父进程(父进程是1130):

 $ ps xao pid,ppid,pgid,sid,comm | grep apache2 1130 1 1130 1130 apache2 23211 1130 1130 1130 apache2 23440 1130 1130 1130 apache2 27038 1130 1130 1130 apache2 27041 1130 1130 1130 apache2 27183 1130 1130 1130 apache2 27242 1130 1130 1130 apache2 27349 1130 1130 1130 apache2 27405 1130 1130 1130 apache2 27456 1130 1130 1130 apache2 27457 1130 1130 1130 apache2 

与10兆字节的常驻内存相比,该父进程占用146兆字节的虚拟内存。 这是使用136兆字节的交换空间的差异!

所以这对我来说没有意义。 我有这么多的空闲内存,但是它使用了更多的交换空间? 根据stackoverflow上的post,他说“意味着没有足够的内存”。 那不是真的。 我有充足的记忆力。

SOpost所做的“换出”结论是错误的。 例如,这是一个简单的程序:

 #include  #include  #include  #include  #include  #include  int main() { printf("Started - sleeping 10s; pid = %i\n", (int)getpid()); sleep(10); int fd = open("10469068800-byte-file", O_RDONLY); void *map = mmap(NULL, 10469068800, PROT_READ, MAP_SHARED, fd, 0); printf("Mapped - sleeping 10s; fd %i to %p\n", fd, map); sleep(10); return 0; } 

当我打印出已启动的消息(在映射的消息之前)后检查ps

 anthony@Zia:~$ ps u 13420 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND anthony 13420 0.0 0.0 4080 348 pts/13 S+ 16:10 0:00 ./test 

之后:

 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND anthony 13420 0.0 0.0 10227780 348 pts/13 S+ 16:10 0:00 ./test 

程序的部分地址空间当前在磁盘上,但这是因为它的内存映射文件尚未被读取(或可能永远不会被读取)。 这个程序也发生了类似的事情:

 #include  #include  #include  #include  int main() { printf("Started - sleeping 10s; pid = %i\n", (int)getpid()); sleep(10); void *mem = malloc(1024*1024*1024); printf("Allocated - sleeping 10s; mem at %p\n", mem); sleep(10); return 0; } 

之前:

 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND anthony 15150 0.0 0.0 4080 352 pts/13 S+ 16:18 0:00 ./test2 

后:

 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND anthony 15150 0.0 0.0 1052660 352 pts/13 S+ 16:18 0:00 ./test2 

在这种情况下,已经分配了内存,但作为优化,内核实际上并没有将实际的内存页放在这些地址之后,直到程序使用它们。 所以,再次,你看到VSZ比RSS高得多。

您可能在Apache中看到了上述两件事(也许还有一些)。 你可以使用pmap -x来讲述。 这是第二个程序(malloc one)的样子:

 anthony@Zia:~$ pmap -x 15997 15997: ./test2 Address Kbytes RSS Dirty Mode Mapping 0000000000400000 4 4 0 rx-- test2 0000000000600000 4 4 4 rw--- test2 00007fba82f94000 1048580 4 4 rw--- [ anon ] <--- HERE 00007fbac2f95000 1672 300 0 rx-- libc-2.17.so 00007fbac3137000 2048 0 0 ----- libc-2.17.so 00007fbac3337000 16 16 16 r---- libc-2.17.so 00007fbac333b000 8 8 8 rw--- libc-2.17.so 00007fbac333d000 16 12 12 rw--- [ anon ] 00007fbac3341000 132 104 0 rx-- ld-2.17.so 00007fbac3533000 12 12 12 rw--- [ anon ] 00007fbac355f000 12 12 12 rw--- [ anon ] 00007fbac3562000 4 4 4 r---- ld-2.17.so 00007fbac3563000 8 8 8 rw--- ld-2.17.so 00007fffb7163000 132 12 12 rw--- [ stack ] 00007fffb71fe000 8 4 0 rx-- [ anon ] ffffffffff600000 4 0 0 rx-- [ anon ] ---------------- ------ ------ ------ total kB 1052660 504 92 

请注意,您可以看到匿名映射,该映射很大但几​​乎没有驻留。 对于使用mmap的程序,您将获得:

 Address Kbytes RSS Dirty Mode Mapping ⋮ 00007f8e50cf2000 10223700 0 0 r--s- 10469068800-byte-file ⋮ 

这表明内存映射文件在那里,但它们都没有驻留。