Потеряна память в Linux - не кешируется, не буферизируется

Мой сервер Ubuntu 12 таинственно теряет / тратит память. Он имеет 64 ГБ оперативной памяти. Около 46 ГБ отображаются как используемые, даже когда я закрываю все свои приложения. Эта память не указывается как используемая для буферов или кэширования.

Результат top (пока мои приложения работают; приложения используют около 9G):

top - 21:22:48 up 46 days, 10:12,  1 user,  load average: 0.01, 0.09, 0.12
Tasks: 635 total,   1 running, 633 sleeping,   1 stopped,   0 zombie
Cpu(s):  0.2%us,  0.2%sy,  0.0%ni, 99.6%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  65960100k total, 55038076k used, 10922024k free,   271700k buffers
Swap:        0k total,        0k used,        0k free,  4860768k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                         
  5303 1002      20   0 26.2g 1.2g  12m S    0  1.8   2:08.21 java                                                                                                                                             
  5263 1003      20   0  9.8g 995m 4544 S    0  1.5   0:19.82 mysqld                                                                                                                                           
  7021 www-data  20   0 3780m  18m 2460 S    0  0.0   8:37.50 apache2                                                                                                                                          
  7022 www-data  20   0 3780m  18m 2540 S    0  0.0   8:38.28 apache2      
  .... (smaller processes)

Обратите внимание, что топовые отчеты 4.8G для кэшированных, а не 48G, и это 55G, которые используются. Результат свободного -m:

             total       used       free     shared    buffers     cached
Mem:         64414      53747      10666          0        265       4746
-/+ buffers/cache:      48735      15678
Swap:            0          0          0

Что использует мою память? Я перепробовал каждую диагностику, с которой мог столкнуться. Форумы забиты людьми, задающими тот же вопрос, потому что Linux использует их оперативную память для буферов / кеша. Кажется, это не то, что здесь происходит.

Может быть уместно, что система является хостом для контейнеров lxc. Наилучшие и бесплатные результаты, представленные выше, получены от хоста, но аналогичное использование памяти сообщается в контейнерах. Остановка всех контейнеров не освобождает память. Некоторые 46G остаются в использовании. Однако, если я перезагружаю хост, память свободна. Это не достигает 46G в ближайшее время. (Я не знаю, если это займет дни или недели. Это займет больше, чем несколько часов.)

Также может иметь значение, что система использует zfs. Zfs считается жадным до памяти, но не настолько. Эта система имеет две файловые системы zfs в двух пулах raidz, один из 1.5T и один из 200G. У меня есть другой сервер, который показывает точно такую ​​же проблему (46G используется никем) и настроен почти одинаково, но с массивом 3T вместо 1.5T. У меня есть много снимков (около 100) для каждой файловой системы zfs. У меня обычно есть один снимок каждой файловой системы, смонтированной в любое время. Размонтирование тех не возвращает мне мою память.

Я вижу, что числа VIRT на скриншоте выше примерно совпадают с используемой памятью, но память остается используемой даже после того, как я закрываю эти приложения - даже после того, как я закрываю контейнер, на котором они работают.

РЕДАКТИРОВАТЬ: я попытался добавить некоторые своп, и что-то интересное произошло. Я добавил 30G свопа. Спустя несколько мгновений объем памяти, помеченный как кэшированный сверху, увеличился с 5G до 25G. Свободно -m указано около 20G более полезной памяти. Я добавил еще 10G подкачки и увеличил кешированную память до 33G. Если я добавлю еще 10 ГБ подкачки, я получу 6 ГБ более распознанным как кэшированный. Все это время сообщается об использовании только нескольких килобайт подкачки. Как будто ядру необходимо иметь соответствующий своп для каждого бита, который он распознает или сообщает как кэшированный. Вот результат вершины с 40G свопа:

top - 23:06:45 up 46 days, 11:56,  2 users,  load average: 0.01, 0.12, 0.13
Tasks: 586 total,   1 running, 585 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  65960100k total, 64356228k used,  1603872k free,   197800k buffers
Swap: 39062488k total,     3128k used, 39059360k free, 33101572k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                         
 6440 1002      20   0 26.3g 1.5g  11m S    0  2.4   2:02.87 java                                                                                                                                             
 6538 1003      20   0  9.8g 994m 4564 S    0  1.5   0:17.70 mysqld                                                                                                                                           
 4707 dbourget  20   0 27472 8728 1692 S    0  0.0   0:00.38 bash      

Любые предложения высоко ценятся.

РЕДАКТИРОВАТЬ 2: Вот значения arc* из /proc/spl/kstat/zfs/arcstats

arc_no_grow                     4    0
arc_tempreserve                 4    0
arc_loaned_bytes                4    0
arc_prune                       4    0
arc_meta_used                   4    1531800648
arc_meta_limit                  4    8654946304
arc_meta_max                    4    8661962768

Там нет L2ARC активирован для ZFS

1 ответ

Скорее всего, эта память используется кешем ZFS ARC и другими данными, относящимися к ZFS, которые хранятся в памяти ядра. Кэш ARC чем-то похож на буферный кеш, поэтому беспокоиться об этом обычно нечего, так как эта память освобождается ZFS, если на это есть спрос.

Однако есть небольшая разница между буферной кэш-памятью и ARC-кэш-памятью. Первый сразу доступен для выделения, а ARC-кеш - нет. ZFS контролирует доступную свободную оперативную память и, когда она слишком мала, освобождает оперативную память для других потребителей

Это прекрасно работает с большинством приложений, но меньшинство из них либо путаются, когда сообщается о небольшом объеме доступной оперативной памяти, либо выделяют слишком много / слишком быструю память для процесса выпуска, чтобы не отставать от скорости.

Вот почему ZFS позволяет уменьшить максимальный размер, который может использовать размер ARC. Эта настройка выполняется в /etc/modprobe.d/zfs.conf файл.

Например, если вы хотите, чтобы ARC никогда не превышал 32 ГБ, добавьте эту строку:

options zfs zfs_arc_max=34359738368

Чтобы получить текущий размер ARC и другую статистику ARC, выполните эту команду:

cat /proc/spl/kstat/zfs/arcstats

size Метрика покажет текущий размер ARC. Помните, что другие области памяти, связанные с ZFS, также могут занимать часть оперативной памяти и не обязательно будут быстро освобождены, даже если они больше не используются. Наконец, ZFS на linux определенно менее развита, чем собственная реализация Solaris, поэтому вы можете столкнуться с такой ошибкой, как эта.

Также обратите внимание, что из-за конструкции общего пула хранения, размонтирование файловой системы ZFS не освободит ни один ресурс. Вам нужно будет экспортировать пул для памяти, которая будет в конечном итоге освобождена.

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