Tuesday, 5 May 2009

Про память: overcommit memory

Почти во всех обсуждениях OOM Killer затрагивался вопрос overcommit. Тут я постараюсь максимально полно рассказать об этих «ручках ядра».

Сейчас в ядре два параметра, отвечающих за overcommit памяти:

  • vm.overcommit_memory — отвечает за стратегию overcommit.
  • vm.overcommit_ratio — отвечает за уровень (в процентах) overcommit

Стратегии. Их сейчас несколько:

  • OVERCOMMIT_GUESS 0 — эвристический подход к распределению памяти. В нем выделяется столько памяти, сколько хочет процесс. Но в swap/res попадает только те страницы, которые используются этим процессом (mm/mmap.c:118).
  • OVERCOMMIT_ALWAYS 1 — overcommit памяти есть всегда. Использовать лучше с совсем кривыми приложениями (mm/mmap.c:112).
  • OVERCOMMIT_NEVER 2 — без overcommit. В этом случае допустимый объем пространства памяти будет total_swap + alowed, где alowed = total_ram * overcommit_ratio / 100 (mm/mmap.c:168).

По умолчанию используется стратегия OVERCOMMIT_GUESS, а vm.overcommit_ratio находится в значение 50% и будет использоват только в случае OVERCOMMIT_NEVER (mm/mmap.c:84).

Хочется отметить, что система всегда резервирует ~3% памяти для процессов пользователя root (mm/mmap.c:132, mm/mmap.c:155, mm/mmap.c:170).

Write on: 15:26 | 11 comments | | tags: , , , | permalink |
Add post to:   Delicious Reddit Slashdot Digg Technorati Google


Add comment

Pingbacks

ST Blog - Отключение OOM Killer в Ubuntu 12.04 @blog.st58.su 25.09.2014 23:54
http://catap.ru/blog/2009/05/05/about-memory-overcommit-memory/
Отключение OOM Killer в Ubuntu 12.04 | Записки на полях @notes.ogloblin.net 27.12.2012 17:35
http://catap.ru/blog/2009/05/05/about-memory-overcommit-memory/

Comments

человек 6.05.2009 9:38

Так а что, всетаки, надо сделать, что бы количество выделяемой памяти было таким же, как оно есть на самом деле? Судя по allowed = (totalram_pages — hugetlb_total_pages())*sysctl_overcommit_ratio / 100;

overcommit_ratio надо ставить в 100, что бы использовалась вся память + своп. А если в системе нет свопа, плюс поставить overcommit_ratio=0, стало быть, память использоваться не будет совсем, так?

И что такое hugetlb_total_pages()?

reply
Kirill A. Korinskiy 7.05.2009 1:17

Окей. Если откинуть факт что на mmap() 1 байта выделяется целая страница, то да — надо ставить sysctl_overcommit_ratio в 100. Если его ставить в 0 и на машине не будет swap, то при выделение любого объема памяти будет происходить ошибка.

В ядре есть просто страницы а есть большие страницы памяти (huge page). Про них я буду рассказывать, но несколько позже. Я думаю поста через 3-4 и до них дойду :)

reply
человек 7.05.2009 14:07

Тогда не понятно, каким местом думали, когда поставили overcommit_ratio в 50 по умолчанию. Логика не ясна. Так же не ясна логика (overcommit_ratio / 100), вместо (1 + overcommit_ratio/100). По логике названия, предполагается, что если стоит 0, стало быть вся память используется, а если 50, стало быть память+50%.

Или, может, я чегото не понимаю? Говорят, же, в последних ядрах убрали вообще этот оом киллер. Не в курсе?

И еще. Простите за ламерский вопрос. Что значит “на mmap() 1 байта выделяется целая страница”? Тоесть получается, что выделяется страница (как я понимаю минимум 64к), а считается все равно 1 байт?? Или я чегото не понял? Или как выделяется, так и считается?

reply
Kirill A. Korinskiy 7.05.2009 17:00

Ну я писал документацию по последнему ядру и я слабо представляю себе как может быть vm в linux без чистильщика.

Про логику это не ко мне — я этот код не писал, я только его читал и вам всем рассказал.

Про последний вопрос я все очень подробно расскажу в следующих статьях. Следите за анонсами :)

reply
человек 8.05.2009 12:29

то есть по-любому без киллера никак? То есть в любом случае может быть ситуация, когда прийдет участковый и всех перестреляет, кто лишний прописан на жилплощади…

ЗА анонсами следим чуть не в онлайне. :) Я пару раз порывался читать про выделение памяти, и понял толко, что есть четыре размера страниц, что для поиска виртуального адреса используются таблицы. А дальше шли структуры описания этих записей про таблицы поиска и про блоки памяти и вот тут уже я ничего не понял (((

reply
Kirill A. Korinskiy 8.05.2009 17:08

Ага. Ибо у нас памяти, идеологически, бесконечно много и любая программа может захотеть использовать сколько угодно. Т.е. мы взяли и mmap’нули файл в 15 тбайт. Кто нам может помешать это сделать? А никто. Пока файл mmap’нут с диска — ал ништяк и как только ram кончится страничка опустится (посути удалиться, а не уйдет в swap). Что нам мешает идеологически mmap’нуть анонимно теже 15 терабайт? Да ничто. А вот обратиться к ним мы скорее всего не сможем, ибо памяти не хватит. Собственно oom killer решает задачу, да радикально, когда программа у которой памяти бесконечно много (в пределах адресации, естественно) пытается захавать больше чем есть у системы.

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

reply
Arxell 12.05.2009 9:16

так чтобы ограничить память на процесс надо выбрать стратегию Always, а чему поставить ratio и как он будет связан с памятью?

reply
человек 12.05.2009 14:57

если я понимаю правильно, то

когда программа отжирает память простым alloc’ом, не пытаясь туда писать, тогда включается алгоримт проверки, сколько памяти ядро может выделить. На это есть два параметра.

vm.overcommit_ratio = 0 vm.overcommit_memory = 2

Если overcommit_memory=0, программа может отожрать порядка 400% от общей памяти (ram+swap), если overcommit_memory=1, то порядка 200%, если overcommit_memory = 2, то по формуле, указанной выше — allowed = (totalram_pages — hugetlb_total_pages())*sysctl_overcommit_ratio / 100 .

Эти параметры не привязаны к процессу. это общесистемные параметры. Влияют они на то, как система рассчитывает количество памяти, доступное всем процессам. По сути, рассчет происходит по фазе луны — давать или не давать еще памяти. А когда ктото хочет использовать память, которую получил, ему не откажут, а просто грохнут соседа. Причем кого грохнуть, решает рулетка… ((( И, главное, что сосед даже зная о том, что его могут грохнуть, никуда не спрячется.

Если интересует, как ограничить память отдельным процессам, это обсуждалось тут

http://www.linux.org.ru/view-message.jsp?msgid=3675145

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

pss: ну и вот еще по теме: http://forum.infobit.ru/viewtopic.php?t=1677

reply
Kirill A. Korinskiy 14.05.2009 19:49

Память на процесс ограничить тяжело. Можно ограничить только перерасход памяти (overcommit). Почему он нужен, я писал тут.

Какой ставить ratio — зависит от условий. Я думаю 50 хватит для почти всех случаев. Можно поставить 100, можно поставить 1. Смотрите формулу в посте и считайте сами сколько у вас получится total_ram.

reply
человек 18.05.2009 12:07

Что будет, после перерасхода памяти, согласно той формуле?

Мне видны следующие варианты: 1) система продолжит выделять физическую память при запросах на запись (уже выделеную malloc()’ом), но новые маллоки будут возвращать falce. 2) маллоки будут возвращать тру, как и раньше, а при попытке использовать память, будет вызван OOM killer.

reply
Kirill A. Korinskiy 18.05.2009 15:21

Out of Memory произойдет при попытке выделить память. И тоже самое при попытки записи в память на выделение которой ее физически нет :)

reply

Comment form for «Про память: overcommit memory»

Required. 30 chars of fewer.

Required.