Назад | Перейти на главную страницу

Избегайте разрыва приложений Linux из-за нехватки памяти

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

Мне любопытно, что делают администраторы, чтобы этого избежать? Это единственное реальное решение для увеличения объема памяти (поможет ли только увеличение объема подкачки?), Или есть лучшие способы настроить коробку с программным обеспечением, чтобы избежать этого? (т.е. квоты или что-то в этом роде?).

По умолчанию Linux имеет несколько поврежденную для мозга концепцию управления памятью: он позволяет вам выделять больше памяти, чем имеет ваша система, а затем случайным образом завершает процесс, когда он попадает в беду. (Фактическая семантика того, что убивают, более сложна, чем это - Google "Linux OOM Killer" для множества деталей и аргументов о том, хорошо это или плохо).


Чтобы восстановить хоть какое-то подобие здравомыслия в управлении памятью:

  1. Отключить OOM Killer (поставить vm.oom-kill = 0 в /etc/sysctl.conf)
  2. Отключить переопределение памяти (поставить vm.overcommit_memory = 2 в /etc/sysctl.conf)
    Обратите внимание, что это троичное значение: 0 = «оценка, если у нас достаточно ОЗУ», 1 = «Всегда говори да», 2 = «Скажи нет, если у нас нет памяти»)

Эти настройки заставят Linux вести себя традиционным образом (если процесс запрашивает больше памяти, чем доступно, malloc () завершится ошибкой, и ожидается, что процесс, запрашивающий память, справится с этой ошибкой).

Перезагрузите компьютер, чтобы он перезагрузился /etc/sysctl.conf, или используйте proc файловую систему включить сразу, без перезагрузки:

echo 2 > /proc/sys/vm/overcommit_memory 

Вы можете отключить избыточную фиксацию, см. http://www.mjmwired.net/kernel/Documentation/sysctl/vm.txt#514

Краткий ответ для сервера - купить и установить больше оперативной памяти.

Сервер, который достаточно опытен OOM (Out-Of-Memory), то помимо опции sysctl диспетчера виртуальных машин (виртуальной памяти) overcommit в ядрах Linux это не очень хорошо.

Увеличение объема подкачки (виртуальной памяти, выгруженной на диск диспетчером памяти ядра) поможет, если текущие значения низкие, и использование включает множество задач, каждый из которых такой большой объем памяти, а не один или несколько обрабатывает каждый запрос огромного количества общей доступной виртуальной памяти (RAM + swap).

Для многих приложений выделение более двух раз (2x) объема ОЗУ в качестве подкачки обеспечивает уменьшение отдачи от улучшения. В некоторых крупных вычислительных симуляторах это может быть приемлемо, если замедление скорости терпимо.

С RAM (ECC или без) быть вполне доступным для скромных количеств, например 4-16 ГБ, признаюсь, сам давно не сталкивался с этой проблемой.

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

Без каких-либо особенностей приложений (например, базы данных, сервера сетевых служб, обработки видео в реальном времени) и использования сервера (несколько опытных пользователей, 100-1000 соединений пользователя / клиента), я не могу придумать каких-либо общих рекомендаций в отношении работы с проблема OOM.

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

Если ваша проблема в том, что вам просто не хватает памяти для запуска необходимых вам сервисов, есть только три решения:

  1. Уменьшите объем памяти, используемый вашими службами, путем ограничения кешей и т.п.

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

  3. Купите больше памяти

Увеличение объема физической памяти может быть эффективным не во всех обстоятельствах.

Один из способов проверить это - команда «поверх». В частности, эти две строки.

Это выходной сервер, когда он был исправен:

MEM | tot   23.7G | free   10.0G | cache   3.9G | buff  185.4M | slab  207.8M |
SWP | tot    5.7G | free    5.7G |              | vmcom  28.1G | vmlim  27.0G |

Когда он работал плохо (и до того, как мы изменили overcommit_memory с 50 до 90, мы увидели поведение с vmcom, работающим на более чем 50 Гбайт, oom-killer запускал процессы каждые несколько секунд, а нагрузка продолжала радикально подпрыгивать из-за взрыва дочерних процессов NFSd постоянно обновляется и воссоздается.

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

Хотя не рекомендуется следовать этому точному маршруту, мы изменили значение overcommit-memory со значения по умолчанию 50 на 90, что частично решило проблему. В итоге нам пришлось переместить всех пользователей на другой терминальный сервер и перезапустить, чтобы увидеть все преимущества.

У меня была аналогичная проблема, связанная с эта ошибка и решением было использовать старое / новое (фиксированное) ядро.

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

echo 3 > /proc/sys/vm/drop_caches

@ voretaq7 linux не имеет уязвимой концепции управления памятью, по умолчанию vm.overcommit_ratio равно 0,

0       -   Heuristic overcommit handling. Obvious overcommits of
            address space are refused. Used for a typical system. It
            ensures a seriously wild allocation fails while allowing
            overcommit to reduce swap usage.  root is allowed to
            allocate slightly more memory in this mode. This is the
            default.

Таким образом, если у вас есть 4 ГБ оперативной памяти и вы попытаетесь выделить 4,2 ГБ с помощью malloc виртуальной памяти, ваше выделение не удастся.

С vm.overcommit_ratio = 1

            1    -   Always overcommit. Appropriate for some scientific
            applications. Classic example is code using sparse arrays
            and just relying on the virtual memory consisting almost
            entirely of zero pages.

С vm.overcommit_ratio = 2

           2    -   Don't overcommit. The total address space commit
            for the system is not permitted to exceed swap + a
            configurable percentage (default is 50) of physical RAM.
            Depending on the percentage you use, in most situations
            this means a process will not be killed while accessing
            pages but will receive errors on memory allocation as
            appropriate.

            Useful for applications that want to guarantee their
            memory allocations will be available in the future
            without having to initialize every page.

Так что по умолчанию linux не перегружает, если у вашего приложения больше памяти, чем у вас есть, возможно, ваш код глючит