Управління пам'яттю в Linux: Swap, OOM Killer та Cgroups

12 хв читання - 31 травня 2026 р.

hero section cover
Зміст
  • Пояснення управління пам'яттю в Linux: swap, OOM killer та cgroups
  • Як Linux управляє сторінками пам'яті
  • Налаштування свопу
  • OOM-кілер
  • Cgroups та обмеження пам'яті
  • Конфігурація пам'яті залежно від ролі сервера
Поділитися

Як працює Linux swap, OOM killer та cgroups - з прикладами конфігурацій для баз даних, веб-серверів та багатокористувацьких VPS-хостів.

Пояснення управління пам'яттю в Linux: swap, OOM killer та cgroups

Linux обробляє пам'ять інакше, ніж більшість операційних систем. Високе використання оперативної пам'яті не завжди є проблемою — ядро активно використовує вільну пам'ять для кешування, щоб пришвидшити читання з диска. Але коли виникає реальне навантаження на пам'ять, спрацюють три механізми: swap, OOM killer та cgroups. Розуміння того, як кожен з них працює та як їх налаштовувати, є різницею між сервером, який плавно сповільнюється під навантаженням, та тим, що виходить з ладу без попередження.

Як Linux управляє сторінками пам'яті

Кожен процес працює у власному віртуальному адресному просторі, розмір якого на 64-бітних системах може досягати 128 ТБ. Ядро відображає ці віртуальні адреси на фізичну оперативну пам'ять за допомогою таблиць сторінок, а буфер перегляду перекладу (TLB) кешує останні запити. Збіг у TLB займає близько 1 наносекунди; промах коштує 20–100 наносекунд, що накопичується у ресурсоємних робочих навантаженнях, таких як бази даних.

Фізична пам'ять поділяється на сторінки розміром 4 КБ, і ядро розділяє їх на дві категорії:

  • Сторінки, підкріплені файлами — пов'язані з файлами на диску. Ядро може видаляти чисті або очищати забруднені без необхідності використання підкачки.
  • Анонімні сторінки — пам'ять купи та стека без файлу-підкладки. Їх необхідно записати в обмінну пам'ять, перш ніж ядро зможе їх звільнити.

На серверах з високими вимогами до пам'яті велика частка анонімних сторінок означає, що своп задіюється на ранньому етапі. Слідкуйте за si (swap in) та so (swap out) у vmstat 1 — постійні значення, відмінні від нуля, є першим сигналом того, що система перебуває під навантаженням.

Для моніторингу використовуйте відповідний інструмент:

ІнструментНайкраще підходить дляКлючовий показник
free -hШвидкий знімок всієї системиavailable колонка
vmstat 1Моніторинг обміну та вводу-виводу в режимі реального часуsi, so
htopІнтерактивний перегляд за процесамиСмуги пам'яті, список процесів
smemТочне використання пам'яті для кожного процесуUSS (розмір унікального набору)
/proc/meminfoДеталі на рівні ядраMemAvailable, Dirty, Slab

Одна поширена помилка: перегляд стовпчика free за стовпцем free -h і панікувати. available — ось що має значення. Вона включає пам'ять, яку ядро може звільнити з кешу за запитом. Сервер, який показує лише 512 МБ вільного простору, але 5 ГБ доступного, не має проблем.

Коли обсяг пам'яті падає нижче порогового значення, kswapd демон ядра починає звільняти сторінки у фоновому режимі. Якщо цього недостатньо, ядро переходить до режиму прямого звільнення, блокуючи процеси доти, доки сторінки не будуть звільнені. Саме звідси беруться стрибки затримки. Налаштуйте сповіщення, коли MemAvailable опускається нижче 10–15% від загального обсягу оперативної пам'яті, щоб у вас був час зреагувати.


 

Налаштування свопу

Своп — це область диска (розділ або файл), куди ядро переміщує неактивні анонімні сторінки, коли оперативна пам'ять заповнюється. Різниця у швидкості є значною: оперативна пам'ять DDR4 має затримку приблизно 100 нс, тоді як SSD-накопичувачі NVMe — близько 100 000 нс, а SSD-накопичувачі SATA — близько 500 000 нс. Обмінна пам'ять є буфером безпеки, а не додатковою оперативною пам'яттю. Сервер, який постійно покладається на обмінну пам'ять, має проблему з пам'яттю, яку збільшення обмінної пам'яті не вирішить.

Використовуйте файл swap замість розділу. Його простіше змінювати за розміром, і для цього не потрібно перерозподіляти розділи.

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Додайте файл, щоб /etc/fstab , щоб зберегти дані після перезавантаження. chmod 600 крок є обов'язковим — будь-які дані, вивантажені з оперативної пам'яті, доступні для читання зі swap, тому файл не повинен бути загальнодоступним для читання.

Після створення свопу налаштуйте vm.swappiness. Значення за замовчуванням 60 є агресивним. Для більшості робочих навантажень хостингу бажано, щоб ядро надавало перевагу оперативній пам'яті та використовувало файл підкачки лише як крайній захід:

Роль сервераvm.swappinessvm.vfs_cache_pressure
Загальний веб-сервер10–2050
База даних (MySQL/PostgreSQL)1–550
За замовчуванням (більшість дистрибутивів)60100

Щодо розміру свопу: 1–2 ГБ достатньо для VPS на 2 ГБ, що обробляє періодичні піки трафіку. На системах з 8 ГБ або більше, фіксований своп розміром 2–4 ГБ зазвичай є достатнім. Мета полягає в тому, щоб надати ядру запобіжний клапан для холодних сторінок, а не розширити загальний обсяг адресованої пам'яті.

На серверах з обмеженим об'ємом оперативної пам'яті та потужним процесором zram створює стиснуту область підкачки в пам'яті, повністю уникаючи дискових операцій вводу-виводу. Це варто врахувати на багатокористувацьких VPS-хостах, де NVMe використовується спільно різними користувачами. Слідкуйте за конфліктами вводу-виводу, якщо підкачка розміщена на тому ж пристрої, що й файли бази даних — інтенсивна підкачка та запис на диск з високою пропускною здатністю погано поєднуються.

OOM-кілер

Коли ядро вичерпує оперативну пам'ять та обмінну зону і не може звільнити достатньо пам'яті іншими засобами, вступає в дію OOM-кілер. Він оцінює процеси за допомогою функції oom_badness() функції:

points = (rss_anon + rss_file + rss_shmem + swapents + pgtables_pages) + (oom_score_adj × totalpages / 1000)

Процес із найвищим балом припиняється. Формула надає перевагу процесам, що споживають багато пам'яті, а ядро уникає припинення декількох процесів поспіль, перевіряючи, чи процес вже не був припинений протягом останніх 5 секунд.

У журналах з'являються два типи подій OOM:

  • Global OOM — у всій системі закінчилися оперативна пам'ять та обмінний простір. Журнали мають префікс Out of memory:
  • Cgroup OOM — контейнер або служба досягли свого memory.max . Префікс у логах Memory cgroup out of memory:

Щоб переглянути минулі події OOM:

dmesg -T | grep -i "out of memory"
journalctl -k --grep="oom"

Зверніть увагу на поле order поле в журналах OOM. Значення, більше за 0, вказує на фрагментацію пам'яті, а не на повне вичерпання — ядро не змогло знайти достатньо суміжних сторінок, навіть маючи вільну пам'ять.

Ви можете вплинути на те, на які процеси націлений OOM-кілер, налаштувавши /proc/<pid>/oom_score_adj. Діапазон значень — від -1000 (ніколи не вбивати) до +1000 (вбивати першими). Для служб, що керуються systemd, налаштуйте це назавжди у файлі модуля:

[Service]
OOMScoreAdjust=-1000

Додаткові параметри sysctl для налаштування поведінки OOM:

ПараметрЗначенняЕфект
vm.overcommit_memory0Режим евристичного перевантаження за замовчуванням
vm.overcommit_memory2Строгий режим; запобігає виділенню пам'яті, що перевищує обсяг оперативної пам'яті × overcommit_ratio + swap
vm.panic_on_oom1Перезавантаження замість завершення процесу
vm.oom_kill_allocating_task1Закриває процес, що викликав OOM, а не найбільшого споживача

Для проактивного моніторингу перевірте /proc/pressure/memory (Pressure Stall Information, доступно починаючи з ядра 4.20). Слідкуйте за some avg10 значення: нижче 5% — нормальний стан, якщо воно тривалий час перевищує 20%, це означає, що ймовірно наближається подія OOM. Зростаючий allocstall лічильника в /proc/vmstat є ще одним раннім сигналом — він підраховує прямі затримки відновлення пам'яті, які часто передують завершенням через OOM. Такі інструменти, як systemd-oomd або earlyoom можуть реагувати на порогові значення PSI до того, як спрацює OOM-кілер ядра.

Cgroups та обмеження пам'яті

Групи контролю (cgroups) дозволяють організовувати процеси в групи та застосовувати жорсткі обмеження ресурсів. Впроваджені в Linux 2.6.24, вони є основою середовищ виконання контейнерів, включаючи Docker, Podman, Kubernetes та LXC. Ядро відстежує використання пам'яті для кожної cgroup, охоплюючи анонімну пам'ять, сторінки, підкріплені файлами, та об'єкти ядра. Якщо cgroup досягає свого обмеження, ядро звільняє пам'ять у межах цієї групи або запускає OOM-kill у межах cgroup.

Cgroup v1 та v2 відрізняються насамперед своєю структурою. V1 монтує кожен контролер (пам'ять, CPU, ввід-вивід) окремо під /sys/fs/cgroup/<controller>/, що призводить до непослідовного відстеження ресурсів. V2 використовує уніфіковану ієрархію на рівні /sys/fs/cgroup/. Kubernetes перейшов на v2 як стандарт у версії 1.25 і припинив підтримку v1 у 1.31.

Щоб перевірити, яку версію використовує ваша система:

stat -fc %T /sys/fs/cgroup/

cgroup2fs означає v2; tmpfs зазвичай означає v1.

ФункціяCgroup v1Cgroup v2
ІєрархіяБагаторівнева, для кожного контролераОдин, уніфікований
Жорстке обмеження пам'ятіmemory.limit_in_bytesmemory.max
М'який ліміт пам'ятіmemory.soft_limit_in_bytesmemory.high (обмеження)
Відстеження використанняmemory.usage_in_bytesmemory.current
Показники навантаженняОбмеженоІнтегрований PSI

Ключові елементи керування пам'яттю в cgroup v2:

ПараметрТипОпис
memory.maxЖорстке обмеженняПеревищення цього значення запускає OOM-кілер
memory.highМ'яке обмеженняОбмежує виділення пам'яті та запускає звільнення пам'яті до досягнення жорсткого обмеження
memory.lowМ'який захистПам'ять нижче цього порогу звільняється останньою
memory.minЖорсткий захистПам'ять нижче цього рівня ніколи не звільняється
memory.swap.maxОбмеження обмінуВстановіть значення 0, щоб вимкнути обмін для цієї групи cgroup
memory.oom.groupЛогічне значенняЯкщо увімкнено, OOM одночасно завершує всі процеси в cgroup

Практичне правило: встановіть memory.high приблизно на 10–20% нижче memory.max , щоб дати ядру простір для відновлення пам'яті до досягнення жорсткого обмеження. При визначенні розміру memory.max, додайте 20–30% понад пікове використання додатка, щоб врахувати кеш сторінок, який враховується у загальному обсязі пам’яті cgroup.

Керуйте cgroups через systemd, а не записуючи безпосередньо у файлову систему cgroup. Використовуйте директиви файлів одиниць, такі як MemoryMax=, MemoryHigh=, та MemoryMin= для постійних обмежень. Для швидких тестів:

systemd-run --scope -p MemoryMax=512M <command>

Для пулів робочих процесів веб-сервера налаштування memory.oom.group=1 забезпечує чисте завершення роботи, якщо один робочий процес перевищує свій ліміт — не залишається ніяких загублених процесів. Для механізмів баз даних memory.min захищає буферний пул від вивільнення під тиском на рівні всієї системи.

Конфігурація пам'яті залежно від ролі сервера

Правильні налаштування пам'яті залежать від того, що робить сервер. Застосування однакової конфігурації до бази даних та веб-сервера PHP зашкодить одному з них.

Роль сервераvm.swappinessСтратегія OOMПолітика Cgroup
База даних1–5Захист (OOMScoreAdjust=-900)Використовуйте memory.min для захисту буферного пулу
Веб-сервер/сервер додатків10–20За замовчуваннямОбмеження на пул робочих процесів через memory.max
Фоновий робочий процес60Можна завершити (OOMScoreAdjust=+200)Регулювання через memory.high
Багатокористувацький VPS60 (з zram)За замовчуваннямЖорстка ізоляція для кожного орендаря за допомогою memory.max

Для MySQL та PostgreSQL виділіть 50–70% доступної оперативної пам’яті для innodb_buffer_pool_size, вимкніть Transparent Huge Pages, щоб зменшити стрибки затримки, та захистіть процес за допомогою OOMScoreAdjust=-900 у файлі модуля systemd.

Для PHP-FPM розмір пулів робочих процесів слід підбирати відповідно до фактичного використання пам'яті. Кожен робочий процес зазвичай використовує 30–100 МБ. Розділіть виділену оперативну пам'ять на середній розмір робочого процесу, щоб отримати безпечне pm.max_children значення. Використовуйте memory.max в cgroups, щоб обмежити пул.

Для робочих навантажень з інтенсивним записом встановіть vm.dirty_ratio на рівні близько 10% та vm.dirty_background_ratio до 3%. Це прискорює очищення забруднених сторінок, запобігаючи значним затримкам вводу-виводу.

Зробіть налаштування ядра постійними, збереживши параметри у /etc/sysctl.d/90-memory.conf. Налаштування, застосовані під час виконання, втрачаються після перезавантаження.

Короткий огляд рекомендованих значень за ролями:

ПараметрВеб-сервер/сервер додатківСервер бази даних
vm.swappiness10–201–5
vm.vfs_cache_pressure5050
vm.dirty_ratio1510%
vm.min_free_kbytes6553665536
Захист від OOMЗа замовчуваннямOOMScoreAdjust=-1000

Якщо ви виконуєте робочі навантаження з високою щільністю і вам потрібен сервер з запасом потужності для належного застосування цих політик, варто звернути увагу на виділені сервери FDC.

Блог

На цьому тижні

Більше статей
Управління пам'яттю в Linux: Swap, OOM Killer та Cgroups

Управління пам'яттю в Linux: Swap, OOM Killer та Cgroups

Як працює Linux swap, OOM killer та cgroups - з прикладами конфігурацій для баз даних, веб-серверів та багатокористувацьких VPS-хостів.

12 хв читання - 31 травня 2026 р.

Посібник з налаштування Prometheus та node_exporter

15 хв читання - 29 травня 2026 р.

Більше статей
background image

Маєте запитання або потребуєте індивідуального рішення?

icon

Гнучкі варіанти

icon

Глобальне охоплення

icon

Миттєве розгортання

icon

Гнучкі варіанти

icon

Глобальне охоплення

icon

Миттєве розгортання