Как работает 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