Комбинация трех фактов вызывает вашу проблему oom:маленький размер страницы , большой VIRT , таблицы страниц . Ваши журналы ясно показывают, что почти вся оперативная память использовалась таблицами страниц, а не памятью процесса (, например, не страницами RESident -, которые в основном были выдавлены для подкачки ).
Проблема с таблицами страниц x86 _64/x86 заключается в том, что когда у вас есть несколько процессов, отображающих одну и ту же область разделяемой памяти, они сохраняют отдельные таблицы страниц. Следовательно, если один процесс сопоставляет 1 ТБ (, включенный в ядро VIRT ), создаст, скажем, 1 ГБ таблиц страниц (, вообще не показанных в top
, поскольку они не считаются принадлежащими процессу ). ]. Но если сто процессов отображают одну и ту же область размером 1 ТБ, они занимают 100 ГБ вашей оперативной памяти для избыточного хранения одних и тех же метаданных!
Количество VIRT одного процесса может быть вызвано просто открытием и отображением файла (, либо именованного, либо "анонимного" ), хотя может быть много альтернативных объяснений.
Я полагаю, что oom killer не учитывает размер таблиц страниц при уничтожении процесса. В вашем случае, по-видимому, mongodb был основным кандидатом на уничтожение oom с точки зрения использования RES. Несмотря на то, что прирост памяти будет незначительным, у системы не было выбора, поэтому она убила то, что могла убить.
Наиболее очевидным способом избежать вашей проблемы было бы использование огромных страниц , если бы только mongodb поддерживал их (Я не предлагаю использовать прозрачные огромные страницы, вместо этого рассмотрите ванильные не -прозрачные огромные страницы ). Беглый поиск говорит, что, к сожалению, mongodb не поддерживает даже не -прозрачные огромные страницы.
Другой способ — ограничить количество порождаемых процессов или как-то уменьшить их размер VIRT.
Для Debian, Ubuntu и Mint:
netcat -h
nc -h
Для Fedora, Red Hat Enterprise Linux и CentOS:
ncat -h
Первая строка этих команд даст версию.