Как работает vm.overcommit_memory?

Когда я использую настройки по умолчанию:

vm.overcommit_memory = 0
vm.overcommit_ratio = 50

Я могу прочитать эти значения из /proc/meminfo файл:

CommitLimit:     2609604 kB
Committed_AS:    1579976 kB

Но когда я меняюсь vm.overcommit_memory от 0 в 2Я не могу запустить тот же набор приложений, который мог запустить до изменения, особенно amarok. Я должен был изменить vm.overcommit_ratio в 300Таким образом, предел может быть увеличен. Теперь, когда я начинаю амарок, /proc/meminfo показывает следующее:

CommitLimit:     5171884 kB
Committed_AS:    3929668 kB

Эта машина имеет только 1 ГБ оперативной памяти, но Amarok работает без проблем, когда vm.overcommit_memory установлен на 0. Но в случае установки его на 2, amarok необходимо выделить более 2 ГБ памяти. Это нормальное поведение? Если да, то может ли кто-нибудь объяснить, почему, например, firefox (который потребляет в 4-6 раз больше памяти, чем amarok) работает одинаково до и после изменений?

3 ответа

Решение

Вы можете найти документацию в man 5 proc ( или на kernel.org):

/proc/sys/vm/overcommit_memory
       This file contains the kernel virtual memory accounting mode.
       Values are:

              0: heuristic overcommit (this is the default)
              1: always overcommit, never check
              2: always check, never overcommit

       In mode 0, calls of mmap(2) with MAP_NORESERVE are not
       checked, and the default check is very weak, leading to the
       risk of getting a process "OOM-killed".

       In mode 2 (available since Linux 2.6), the total virtual
       address space that can be allocated (CommitLimit in /proc/mem‐
       info) is calculated as

           CommitLimit = (total_RAM - total_huge_TLB) *
                         overcommit_ratio / 100 + total_swap

Простой ответ заключается в том, что установка overcommit на 1, установит сцену так, что когда программа вызывает что-то вроде malloc() выделить кусок памяти (man 3 malloc), он всегда будет успешным независимо от того, знает ли система, что у нее не будет всей запрошенной памяти.

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

пример

Чтобы подчеркнуть, почему это иногда может иметь значение, взгляните на указания Redis о том, почему vm.overcommit_memory должно быть установлено в 1 для этого.

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

Прежде всего, когда vm.overcommit_memory = 0, то vm.overcommit_ratioзначение не имеет значения. Ядро будет использовать эвристический алгоритм для перегрузки памяти, так что ваш amarok процессу может быть выделено больше памяти, чем доступно.

Когда вы устанавливаете vm.overcommit_memory к 2, то vm.overcommit_ratioзначение становится актуальным. По умолчанию это значение установлено на 50, что означает, что система будет выделять только до 50% вашей оперативной памяти (плюс своп). Это объясняет, почему вы не можете запускать программы, которые были нормальными, когда vm.overcommit_memory = 0 - потому что выделяемой памяти меньше 500 МБ (при условии отсутствия подкачки).

Когда вы установите его на 300, вы позволяете системе выделять до 300% вашей оперативной памяти (плюс своп, если таковой имеется), поэтому CommitLimit ценность в /proc/meminfo так высоко.

Хотя vm.overcommit_memory = 2обычно используется для предотвращения чрезмерных обязательств, здесь вы используете его для ограничения суммы, которая может быть превышена. Установив его на 300 опасно, поскольку в вашей системе нет 5171884 kB памяти, и поэтому, в зависимости от того, сколько места подкачки у вас есть, система будет использовать подкачку (что медленно) или вообще будет не хватать памяти.

Что касается почему amarok использует больше памяти, когда vm.overcommit_memory = 2 - это наверное потому, что amarokлучше всего работает с большим объемом памяти, но вполне подходит и с меньшим объемом памяти. Таким образом, логика программы может сначала попытаться выделить 2 ГБ памяти, но если это не удается, попробуйте 1 ГБ.

Ядро Linux поддерживает следующие режимы обработки превышения лимита.

0 — эвристическая обработка превышения лимита. Очевидное превышение адресного пространства отвергается. Используется для типичной системы. Это гарантирует, что резкое выделение не удастся, в то же время позволяя использовать чрезмерную фиксацию для сокращения использования подкачки. В этом режиме root может выделить немного больше памяти. Это значение по умолчанию.

1 – Всегда переусердствуйте. Подходит для некоторых научных применений. Классический пример — код, использующий разреженные массивы и полагающийся только на виртуальную память, почти полностью состоящую из нуля страниц.

2 – Не переусердствуйте. Общий объем выделенного адресного пространства для системы не может превышать swap + настраиваемый объем (по умолчанию — 50%) физической оперативной памяти. В зависимости от объема, который вы используете, в большинстве ситуаций это означает, что процесс не будет завершен при доступе к страницам, но будет получать соответствующие ошибки при выделении памяти.

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

https://www.kernel.org/doc/Documentation/vm/overcommit-accounting

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