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

50

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

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, таким образом , предел может быть увеличен. Теперь, когда я запускаю amarok, /proc/meminfoпоказывает следующее:

CommitLimit:     5171884 kB
Committed_AS:    3929668 kB

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

Михаил Морфиков
источник

Ответы:

67

Вы можете найти документацию в 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.

Кайл Брандт
источник
2
Но не должно ли значение Committed_ASбыть одинаковым в обоих случаях?
Михаил Морфиков
@MikhailMorfikov: Теоретически, я верю в это, но кто знает, что делают эти программы. Хотелось бы увидеть более контролируемую среду с простой программой, которая просто распределяет, скажем, оперативную память через Malloc. А затем запустите тест после перезагрузки между тестами.
Кайл Брандт
Хорошо, так что я останусь с 0сейчас.
Михаил Морфиков
2
@MikhailMorfikov: Да, практически я думаю, что 0 имеет смысл. В моей среде я включаю только один раз для Redis, который выполняет то, что, как он ожидает , требует больше памяти, которую он использует из-за fork (). Ребенок будет в значительной степени использовать все те же страницы памяти, но Linux не знает, что говорит о безопасности, он должен предполагать, что будет использоваться 2x память (если вы хотите узнать больше: redis.io/topics/faq )
Kyle Брандт
не должно ли последнее утверждение в вашем ответе начинаться как «с включения overcommit»? потому что установка его в 1 означает, что вы просите, чтобы он был overcommit, верно?
просит