Я получаю неожиданное поведение, когда моей машине не хватает памяти.
У меня Intel i7-6700 с 32 ГБ оперативной памяти, и я использую Arch Linux с ядром vanilla 4.14.8. У меня есть подкачка 32 ГБ на зашифрованном томе LVM на диске SSD.
Во время нормальной работы я запускаю пару гостей QEMU/KVM, а также другие вещи (XFCE, Firefox и т.д.). Нормальное использование памяти составляет около 20-30%, почти без подкачки.
Но когда я запускаю что-то интенсивное использование памяти (например, 7za a -md=29
для сжатия большого файла), система зависает / зависает, когда использование памяти достигает 100%. Клавиатура и мышь перестают реагировать полностью, экран зависает, активность диска прекращается, и любые TCP-соединения с компьютером зависают в фазе SYN. Единственный способ выйти из этой ситуации - выключить и снова включить двигатель.
В момент, непосредственно перед зависанием, видно, что пространство подкачки практически не используется. Конечно, подкачка включена, и я не использую какие-либо конкретные настройки sysctl, связанные с памятью (в частности, мой vm.swappiness имеет значение по умолчанию 60).
Что я не понимаю, так это:
- Почему ядро не использует пространство подкачки?
- Почему убийца не запускается, когда память исчерпана?
Я не эксперт по ядру, но, насколько я понимаю, система не должна зависать / зависать при нехватке памяти. То, что я ожидал бы увидеть это:
- Когда доступно пространство подкачки, ни один процесс не должен быть убит, пока не будут использованы и память, и своп (в моем случае 64G).
- Даже без обмена, oom-killer должен убить
7za
когда заканчивается память - Даже без обоих вышеперечисленных действий любой процесс, пытающийся выделить больше памяти, чем доступно, должен получить ошибку и завершиться неудачей.
Таким образом, на самом деле существует 3 независимых механизма предотвращения нехватки памяти, но все они, похоже, дают сбой. Я понимаю, что могут быть некоторые тонкие проблемы, о которых я не знаю (например, раздувание памяти в гостевых виртуальных машинах, заблокированная память и т.д.), Но я действительно не могу придумать ничего, что могло бы объяснить поведение, которое я вижу.
Может кто-нибудь объяснить, что здесь происходит и почему? Я что-то пропустил? Могу ли я сделать что-нибудь для детерминированного предотвращения зависания?
РЕДАКТИРОВАТЬ:
Я провел несколько дифференциальных тестов и обнаружил, что:
- Зашифрованный обмен на томе LVM => машина зависает.
- Зашифрованный своп на разделе => все в порядке (своп используется как положено, машина не зависает).
Казалось бы, проблема как-то связана с LVM. В обоих случаях я использовал один и тот же физический раздел, поэтому он не связан с диском. Во время тестов я оставил vm.swappiness до 60 (по умолчанию).
Как примечание: во время одного конкретного теста я заметил, что в htop одна метка появилась в панели подкачки непосредственно перед тем, как машина замерзла. Таким образом, ядро фактически начало использовать своп, но это продолжалось всего около 3 секунд.
Проблема должна быть легко воспроизводимой.