Як працює 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. Але у випадку встановлення на неї 2, Amarok потрібно виділити більше 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), вона завжди матиме успіх незалежно від того, чи знає система, що у неї не буде всієї пам’яті, що є попросили.

Основою для розуміння є ідея віртуальної пам'яті . Програми бачать віртуальний адресний простір, який може бути, а може і не бути, відображений у фактичну фізичну пам'ять. Відключивши перевірку надмірної комісії, ви повідомляєте ОС просто припускати, що фізичної пам'яті завжди достатньо для резервного копіювання віртуального простору.

Приклад

Щоб виділити, чому це іноді може мати значення, погляньте на вказівки Redis щодо того, чому vm.overcommit_memoryслід встановити його 1.


2
Але чи не повинно значення Committed_ASбути однаковим в обох випадках?
Михайло Морфіков

@MikhailMorfikov: Теоретично я в це вірю, але хто знає, що ці програми роблять. Хочеться побачити більш контрольоване середовище з простою програмою, яка просто виділяє, наприклад, концерт барана через Malloc. А потім запустіть тест після перезавантаження між тестами.
Кайл Брандт

Гаразд, тому я поки що залишатимусь 0.
Михайло Морфіков

2
@MikhailMorfikov: Так, практично я думаю, що 0 має найбільш сенс. У моєму середовищі єдиний раз, коли я вмикаю 1, - це Redis, який робить речі там, де, як очікується , вимагає набагато більше пам’яті, яку він використовує завдяки fork (). Дитина в значній мірі використовуватиме все ті самі сторінки пам’яті, але Linux не знає, що каже, що це безпечно, він повинен припустити, що буде використано 2x пам'ять (якщо ви хочете дізнатися більше: redis.io/topics/faq )
Kyle Брандт

чи не має останнє твердження у вашій відповіді починатись таким чином, як "включення перезавантаження"? тому що встановити його на 1 означає, що ви просите його перевиконати, правда?
асгс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.