Сравнение размера виртуальной памяти с резидентным размером

Я столкнулся с этим сообщением stackoverflow:

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 удаляет заголовки столбцов, таким образом, я искусственно добавляю их назад),

Посмотрите, сколько большей виртуальной памяти сравнивается с резидентной памятью. Я имею в виду, например, для апачского родительского процесса (родительский процесс является 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

Тот родительский процесс поднимает 146 мегабайтов виртуальной памяти по сравнению с 10 мегабайтами резидентной памяти. Вот в чем разница 136 мегабайтов используемой области подкачки!

Таким образом, это не имеет смысла мне. У меня есть так много свободной памяти, но она использует настолько больше области подкачки?? Согласно сообщению на stackoverflow, он говорит "средства нет достаточной памяти". Хорошо это не верно. У меня есть много памяти.

0
задан 23 May 2017 в 15:39

1 ответ

«Подкачанный» вывод, который делает сообщение SO, неверен. Например, вот тривиальная программа:

#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;
}

Когда я проверяю 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 <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;
}

До:

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):

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

Обратите внимание, что вы можете увидеть анонимное отображение, которое огромно, но почти ничего не имеет. Для программы с mmap вы получите:

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

Это показывает, что файл с отображенной памятью есть, но он не является резидентным.

0
ответ дан 23 May 2017 в 15:39

Другие вопросы по тегам:

Похожие вопросы: