A conclusão "trocada" da postagem SO está errada. Por exemplo, aqui está um programa trivial:
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
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;
}
Quando eu verifico ps
depois que ele imprime a mensagem iniciada (antes da mensagem mapeada ):
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
e depois:
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
Parte do espaço de endereço do programa está atualmente no disco, mas isso é porque é um arquivo mapeado na memória que ainda não foi lido (ou talvez nunca seja). Uma coisa semelhante acontece com este programa:
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
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;
}
Antes:
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
Depois:
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
Neste caso, a memória foi alocada mas, como uma otimização, o kernel não coloca páginas reais de memória atrás desses endereços até que o programa os use. Então, novamente, você vê um VSZ muito maior que o RSS.
Você provavelmente está vendo as duas coisas acima (e talvez mais algumas) no Apache. Você pode usar pmap -x
para contar. Aqui está o que o segundo programa (o malloc) se parece:
anthony@Zia:~$ pmap -x 15997
15997: ./test2
Address Kbytes RSS Dirty Mode Mapping
0000000000400000 4 4 0 r-x-- test2
0000000000600000 4 4 4 rw--- test2
00007fba82f94000 1048580 4 4 rw--- [ anon ] <--- HERE
00007fbac2f95000 1672 300 0 r-x-- 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 r-x-- 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 r-x-- [ anon ]
ffffffffff600000 4 0 0 r-x-- [ anon ]
---------------- ------ ------ ------
total kB 1052660 504 92
Note que você pode ver o mapeamento anônimo que é enorme, mas não tem quase nada residente. Para o programa com o mmap
, você obtém:
Address Kbytes RSS Dirty Mode Mapping
⋮
00007f8e50cf2000 10223700 0 0 r--s- 10469068800-byte-file
⋮
Isso mostra que o arquivo de memória mapeada está lá, mas nenhum dele é residente.