воскресенье, 11 августа 2013 г.

Черезмерное выделение памяти (overcommit)

Overcommit - стратегия выделения памяти, когда операционная система разрешает приложениям занимать больше виртуальной памяти, чем доступно в системе.

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

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

Стратегии у vm.overcommit_memory могут быть три:

OVERCOMMIT_ALWAYS (значение выставлено в 1) — ядро всегда удовлетворяет любые запросы на выделение памяти. Реально страницы памяти будут выделяться при первом обращении к ним.
OVERCOMMIT_GUESS (значение 0) — эвристический подход к распределению памяти. Используется по умолчанию, ибо подходит для большинства задач. Система будет отвергать только запросы, которые в принципе не могут быть удовлетворены, остальные — удовлетворять вне зависимости от наличия свободной памяти. На деле практически не отличим от OVERCOMMIT_ALWAYS.
OVERCOMMIT_NEVER (значение 2) — работа вообще без overcommit. Полный объём памяти, исходя из которого будут удовлетворяться или отвергаться запросы на выделение памяти, вычисляется как total_swap + total_ram * overcommit_ratio / 100. Значение параметра vm.overcommit_ratio имеет значение только при этой стратегии. Таким образом, при overcommit_ratio < 100, система всегда будет выделять память только если она подкреплена реальными страницами в ОЗУ или свопе. При overcommit_ratio > 100 мы получаем режим, схожий с OVERCOMMIT_GUESS, но с явно установленным «ограничителем».

Стоит заметить, что операционная система всегда резервирует около трех процентов памяти для процессов пользователя root.

Политики OVERCOMMIT_GUESS и OVERCOMMIT_ALWAYS приводит к ситуациям, когда суммарный размер виртуальной памяти приложений может намного превосходит реально имеющийся объем ОЗУ и свопа. В теории, когда реальная память заканчивается, в Linux срабатывает OOM Killer, убивающий лишние, самые «невыгодные» с точки зрения ядра, процессы. На практике же, OOM Killer отрабатывает далеко не всегда: система может уйти в длительный лаг или зависнуть.

Установим режим выделения памяти не больше, чем есть (OVERCOMMIT_NEVER), по умолчанию стоит выделять сколько запросит процесс (OVERCOMMIT_GUESS):

# sysctl vm.overcommit_memory=2
# sysctl vm.overcommit_ratio=80
Значение параметра vm.overcommit_ratio по-умолчанию равно 50. Чтобы изменения сохранились после перезагрузки пишем:

# echo 2 > /proc/sys/vm/overcommit_memory
# echo 80 > /proc/sys/vm/overcommit_ratio

Однако при этих параметрах появились случаи, когда браузер вдруг начинал дико свапироваться на диск, а потом обратно в память - система при этом сильно тормозила.

Комментариев нет:

Отправить комментарий