Как работает swappiness в Linux: мифы, механика и практические рекомендации

- Swappiness не задаёт порог использования ОЗУ для начала свопа. Это неверный, но распространённый миф. Swappiness задаёт относительную приоритетность сканирования анонимных страниц и страниц, связанные с файлами.
- Значение swappiness влияет на отношение anon_prio к file_prio; более высокое значение повышает приоритет выгрузки анонимных страниц в swap, низкое — повышает вероятность освобождения страничной памяти, восстанавливаемой из файлов.
- Триггеры включения механизма освобождения памяти основаны на «водных метках» зон (high/low water marks) и других внутренних порогах ядра, а не на одном единственном значении swappiness.
В этой статье подробно разбираем, как именно работает swappiness, почему классическое объяснение неверно, какие ещё факторы влияют на поведение системы и как безопасно экспериментировать с настройкой.
Основная цель и варианты запроса
Основной запрос: понять, что делает параметр vm.swappiness в Linux и как на практике его настраивать.
Сопутствующие варианты запросов, которые мы покрываем:
- что такое swappiness
- vm.swappiness как работает
- настроить swappiness ubuntu
- когда стоит уменьшать swappiness
- влияние swappiness на производительность
Important: перед изменением любого системного параметра делайте резервную копию конфигурации и, по возможности, тестируйте на стенде.
Что обычно говорят — и почему это вводит в заблуждение
Широко распространённая формулировка: «swappiness задаёт порог использования ОЗУ, при достижении которого начнёт использоваться swap». Это упрощение — слишком буквально понимание, и оно не отражает механики ядра. На самом деле swappiness регулирует относительную «агрессивность» ядра при выборе, какие типы страниц сканировать и отдавать на выгрузку: анонимные или file-backed.
Мы разберём: зоны памяти, страницы, приоритеты anon_prio/file_prio, моменты, когда запускается сканирование для освобождения памяти, и практические рекомендации по настройке и тестированию.
Коротко о понятиях (глоссарий в одной строке)
- Страница: минимальная единица выделения памяти в ядре (обычно 4 KB).
- File-backed page: страница, содержащая данные, которые могут быть повторно считаны из файла на диске.
- Anonymous page: страница без файловой основы — её содержимое нужно сохранять в swap, если его хотят сохранить.
- Zone: область физической памяти (DMA, DMA32, Normal, HighMem) — разбиение по возможностям доступа и архитектуре.
- Node: NUMA-узел, сопоставлен с процессором в системах NUMA.
- Water marks: низкая/высокая «водная» метка зоны, при достижении которой начинается активное сканирование.
Раздел 1. Память Linux устроена не как одна куча
Linux рассматривает ОЗУ как несколько зон (zones), а зоны связаны с узлами (nodes). Какие именно зоны присутствуют — зависит от архитектуры (32/64-bit) и объёма памяти.
Упрощённый список зон на архитектуре x86:
- Direct Memory Access (DMA): низкие 16 МБ. Историческое назначение для устройств, ограниченных этой областью.
- Direct Memory Access 32 (DMA32): низкие 4 ГБ (обычно присутствует в 64-bit ядрах). Название связано с ограничениями старых 32-битных DMA.
- Normal: память выше 4 ГБ на 64-bit машинах (или промежуток 16 МБ–896 МБ на 32-bit).
- HighMem: только на 32-bit ядрах — память выше ~896 МБ.
Практический смысл: при аллокации память стараются брать из node, связанного с CPU, на котором выполнится процесс. В простых системах есть только node 0 и все зоны принадлежат ему.
Файл /proc/buddyinfo показывает, какие зоны есть и в каком они состоянии. Пример вывода на изучаемой машине:
less /proc/buddyinfoПример строки (в исходной статье):
Node 0, zone DMA 1 1 1 0 2 1 1 0 1 1 3
Node 0, zone DMA32 2 67 58 19 8 3 3 1 1 1 17Каждое число описывает количество свободных «блоков» определённого размера (кратно степени двойки страниц). Мы не будем подробно разбирать buddy-алгоритм здесь, но важно понимать: ядро отслеживает свободные слоты по степеням двойки и использует их при аллокации.
Раздел 2. PAGESIZE — основная единица
Страницы имеют фиксированный размер, выбираемый ядром при загрузке. На большинстве современных Linux систем это 4096 байт (4 KB). Проверить размер страницы можно командой:
getconf PAGESIZEЭтот размер важен для расчёта количества страниц в water mark и при переводе страниц в байты.
Раздел 3. Типы отображений памяти (mappings)
Ядро работает со страницами, которые связаны с разными типами отображений:
- File backed — данные загружены из файла. Их можно восстановить, прочитав файл заново; если данные изменились, их надо записать обратно в файл перед освобождением.
- Anonymous — страницы без файла. Это динамические объекты: стек, куча, буферы времени выполнения. Их можно сохранить только в swap.
- Device backed — отображение в память устройств (например, mmap блок-устройств).
- Shared — несколько процессов разделяют одну страницу для IPC.
- Copy on write — оптимизация для fork: копирование памяти происходит при попытке записи.
Для swappiness нас интересуют прежде всего первые два типа: file-backed и anonymous.
Раздел 4. Что такое swappiness на уровне кода
В ядре есть глобальная настройка vm_swappiness с диапазоном 0..100, значение по умолчанию — 60. В исходниках vmscan.c видно, что:
/*
* From 0 .. 100. Higher means more swappy.
*/
int vm_swappiness = 60;Дальше значение swappiness читается в локальной переменной swappiness:
int swappiness = mem_cgroup_swappiness(memcg);Затем ядро вычисляет два приоритетных коэффициента:
anon_prio = swappiness;
file_prio = 200 - anon_prio;Иными словами, swappiness не является «порогом», это коэффициент, задающий относительную приоритетность для обработки двух классов страниц.
Раздел 5. Золотое отношение: anon_prio против file_prio
Почему такое соотношение имеет смысл? Рассмотрим логику:
- File-backed страницы можно отбросить из ОЗУ и затем при следующем обращении просто перечитать из исходного файла. Часто это дешевле, чем держать их в swap (особенно если данные редко используются).
- Anonymous страницы содержат значения, которые нельзя восстановить из файла; их нужно сохранить (в swap) чтобы не потерять состояние.
Если ядро при освобождении памяти предпочитает сканировать file-backed страницы (высокий file_prio), то освобождение будет происходить путём выброса страниц, которые легко восстановить — это ведёт к повышению IO чтений файлов в будущем, но уменьшает swap churn. Обратно, если повышен anon_prio, ядро будет склонно свопить анонимные страницы и держать file-backed страницы в ОЗУ, что ведёт к использованию swap, но потенциально уменьшает последующие обращения к файловой системе.
Важное уточнение: это всё — относительные предпочтения при сканировании. Фактический момент начала свопа определяется другими порогами (water marks) и общей политикой управления памятью.
Раздел 6. Когда действительно начинается своп
Каждая зона имеет низкую (low) и высокую (high) водные метки — это внутренние пороги, выраженные в страницах. Когда доступная память в зоне падает ниже low water mark, ядро инициирует активное сканирование и попытки освобождения сторожевых страниц с учётом anon_prio и file_prio.
Проверить значения зон можно в /proc/zoneinfo:
less /proc/zoneinfoПример: для зоны DMA32 в тестовой машине low = 13966 страниц, high = 16759 страниц.
Поведение при swappiness = 0: ядро будет откладывать инициирование swap-операций до тех пор, пока сумма свободных страниц и file-backed страниц не станет меньше high water mark. Это значит — swappiness=0 не выключает swap полностью; оно лишь меняет правило, по которому сканирование выбирает страницы.
Ключевая мысль: swappiness не даёт «если-then» порога по использованию ОЗУ, она влияет на то, какие страницы будут рассматриваться для выгрузки, когда ядро уже решило, что памяти не хватает.
Раздел 7. Практические рекомендации по настройке
Общие факторы, которые надо учитывать:
- Тип носителя: SSD и NVMe гораздо быстрее, чем старые механические диски. На SSD своп менее болезнен по задержке, но износ флеш-чипов тоже может быть фактом для некоторых сценариев.
- Нагрузка и профиль приложения: десктоп с интерактивной работой, сервер базы данных, потоковые службы, контейнеры — для каждого типа есть свои компромиссы.
- Наличие специализированного кэша у приложения (например, СУБД): приложения с собственным менеджментом памяти могут требовать особых настроек.
Конкретные советы:
- По умолчанию оставьте значение 60 для общего десктопа/серверов, если нет явных проблем.
- Если на старых механических дисках вы видите значительные задержки из-за swap churn, попробуйте снизить swappiness, например до 30–10, и наблюдайте; не забудьте следить за частотой записи/чтения файлов.
- На серверах БД используйте рекомендации поставщика ПО; иногда поставщики явно советуют уменьшить swappiness.
- Для систем с ограниченной памятью и интенсивной работой с heap (контейнеры) стоит экспериментировать в профилированной среде.
Как изменить и сделать изменение постоянным:
Проверить текущее значение:
cat /proc/sys/vm/swappinessВременно изменить:
sudo sysctl vm.swappiness=45Чтобы сделать изменение постоянным, добавьте строку в /etc/sysctl.conf:
vm.swappiness=35(Замените 35 на желаемое значение.)
Сделайте: sudo nano /etc/sysctl.conf, добавьте строку, сохраните.
Важно: при перезагрузке значение вернётся к дефолту, если вы не поменяете sysctl.conf или не примените через systemd-tmpfiles/инициализацию.
Раздел 8. Что может пойти не так — контрпримеры и случаи, когда swappiness не помогает
- Сценарий: приложение создаёт тысячи короткоживущих аллокаций — swappiness здесь не поможет снизить пиковое потребление, если проблема в дизайне приложения. Лучше профилировать приложение.
- Сценарий: на машине с очень медленным HDD уменьшение swappiness снижает swap, но повышает количество операций записи/чтения к файловой системе (page cache churn), что в сумме хуже. Здесь нужен баланс.
- Сценарий: пользователь думал, что «много используемой» RAM = проблема — но Linux использует свободную память для кеширования, и это нормально. Менять swappiness по этому поводу бессмысленно.
Раздел 9. Альтернативные подходы управления памятью
- Контроль через cgroups (memory.memsw.limit_in_bytes и другие параметры) для ограничения использования памяти контейнерами.
- Использование zram/zswap (компрессия страниц в оперативной памяти) для снижения IO на диск.
- Тюнинг параметров VM: dirty_ratio, dirty_background_ratio, vfs_cache_pressure (влияет на политику очистки кэша) и другие. Эти параметры меняют сопутствующие механики управления памятью, но тоже требуют тестирования.
Раздел 10. Как наблюдать и тестировать
Полезные команды и файлы для мониторинга и диагностики:
- free -h — общий обзор использования памяти и swap.
- vmstat 1 — потоковое наблюдение за page in/out, swap in/out.
- sar -B — статистика о страницах (если установлен sysstat).
- top/htop — обзор процессов и их использования памяти.
- /proc/meminfo — детальная статистика по памяти.
- /proc/zoneinfo — water marks и статистика по зонам.
- /proc/vmstat — множество счётчиков, включая pgmajfault, pgpgin/pgpgout и пр.
Пример теста (контролируемая нагрузка):
- Задайте начальное значение swappiness и сохраните метрики (vmstat, iostat, dstat).
- Запустите тестовую нагрузку, имитирующую рабочую нагрузку (например, memtester, stress-ng с параметрами по памяти или реальное приложение в стенде).
- Измерьте латентность и throughput приложения, IO активность и количество swap in/out.
- Измените swappiness на другой уровень и повторите.
- Сравните результаты качественно: изменение в одну сторону может улучшать какие-то метрики и ухудшать другие.
Критерии приёмки
- Нагрузка системы не превышает допустимых латентностных порогов приложения.
- Swap churn (частые записи/чтения в swap) снизился без пропорционального увеличения IO к файловой системе, если цель — снизить обращение к swap.
- Нет значительного увеличения количества page faults, ухудшающих производительность.
Раздел 11. Чек-листы по ролям
Администратор сервера:
- Оцените тип дисков (HDD/SSD/NVMe).
- Соберите базовую телеметрию (vmstat, iostat, /proc/meminfo).
- Протестируйте изменение swappiness в ненагрузочном окне.
- Настройте постоянную конфигурацию в /etc/sysctl.conf.
Разработчик приложения:
- Профилируйте использование памяти приложения (heap, утечки).
- Рассмотрите возможность управления кешем и внутренними структурами приложения.
- Предпочтите масштабирование по горизонтали при необходимости.
Десктоп-пользователь:
- Оставьте значение по умолчанию, если нет проблем.
- Если наблюдается «подвисание» при активации свопа, попробуйте снизить swappiness и посмотрите поведение.
Раздел 12. SOP для изменения swappiness и отката
- Сохраните текущее значение: current=$(cat /proc/sys/vm/swappiness)
- Примените тестовое значение: sudo sysctl vm.swappiness=30
- Наблюдайте 24–72 часа в рабочей нагрузке: vmstat, top, iostat.
- Если результат удовлетворительный, добавьте vm.swappiness=30 в /etc/sysctl.conf.
- Если ухудшение, верните старое значение: sudo sysctl vm.swappiness=$current и удалите/отредактируйте строку в /etc/sysctl.conf.
Rollback: держите план отката и запись метрик до и после для быстрого анализа.
Раздел 13. Тестовые случаи и критерии приёмки
Тестовые сценарии:
- Маленькая система, много мелких процессов, интерактивная работа: цель — минимальные задержки UI.
- СУБД сервер: цель — стабильная латентность запросов.
- Файловый сервер: цель — максимальный throughput ввода/вывода.
Acceptance criteria (пример):
- Средняя латентность запросов не выросла более чем на 10% при изменении swappiness.
- Количество swap in/out не превышает заранее установленного порога для конкретного профиля.
- Нет увеличения числа несовместимых page faults, вызывающих thrashing.
Раздел 14. Ментальные модели и эвристики
- Swappiness — это регулятор «куда» смотреть при недостатке памяти, а не «когда» начинать своп.
- Представьте ядро как гардеробщика: когда шкаф переполнен, оно решает, что убрать — старые вещи (file-backed) или личные вещи (anonymous). Swappiness подсказывает, что отдавать предпочтение для уборки.
- Всегда думайте в терминах компромисса: меньше swap ↔ больше чтений из файлового кеша.
Раздел 15. Матричная сводка и сравнение подходов
| Подход | Плюсы | Минусы | Когда применять |
|---|---|---|---|
| swappiness = 60 (по умолчанию) | Баланс между swap и file-backed | Универсальный, не оптимален для специфичных нагрузок | Общие серверы и рабочие станции |
| swappiness = 0–10 | Снижает свопинг анонимных страниц | Может повысить файловые IO | Системы с медленным swap и критичной чувствительностью к свопу |
| swappiness = 80–100 | Более активное свопирование анонимных страниц | Может увеличить swap activity | Системы с быстрыми swap (NVMe) и большую выгоду от удержания file-cache |
Раздел 16. Risk matrix и смягчения
- Риск: чрезмерный swap churn → деградация производительности. Смягчение: снизить swappiness, добавить RAM, включить zram.
- Риск: усиление файловых операций → увеличение latency файловых сервисов. Смягчение: мониторинг IO, балансировка нагрузки, SSD вместо HDD.
- Риск: неправильное изменение в проде → потеря SLA. Смягчение: тестирование на стенде, постепенное развертывание.
Раздел 17. Безопасность и конфиденциальность
Swap может содержать содержимое памяти, включая секреты. Если в вашей среде требуется соответствие политике безопасности:
- Рассмотрите шифрование swap (например, encrypted swap на LUKS).
- Используйте механизмы secure-erase/шифрование устройств, если на диске хранятся чувствительные данные.
- Помните о риске компрометации через дампы памяти и core-файлы.
Раздел 18. Советы по миграции и совместимости
- Если вы переносите VM на другой хост, убедитесь, что target host имеет аналогичные свойства дисковой подсистемы; настройка swappiness может вести себя по-разному на SSD и HDD.
- Контейнеры: настройка на уровне хоста и cgroups может пересекаться — учитывайте ограничения memory не только через swappiness.
Раздел 19. Примеры сценариев и шаблоны конфигураций
Шаблон для /etc/sysctl.conf (пример):
# Тонкая настройка VM
vm.swappiness=35
vm.vfs_cache_pressure=50Шаблон для быстрого теста:
- Сохранить текущее значение: old=$(cat /proc/sys/vm/swappiness)
- Установить тестовое: sudo sysctl vm.swappiness=10
- Записать результаты мониторинга в лог.
- Восстановить: sudo sysctl vm.swappiness=$old
Раздел 20. Decision tree (Mermaid)
flowchart TD
A[Наблюдаем проблемы с памятью] --> B{Есть ли swap и быстрый ли диск?}
B -- Да, быстрый --> C[Можно увеличить swappiness]
B -- Нет или HDD --> D[Рассмотреть уменьшение swappiness]
C --> E{Производительность улучшилась?}
D --> E
E -- Да --> F[Сделать изменение постоянным в /etc/sysctl.conf]
E -- Нет --> G[Провести профилирование приложений и рассмотреть увеличение RAM или zram]
G --> H[Вернуться к тестированию]Раздел 21. Короткий чек-лист для быстрого действия
- Посмотреть vm.swappiness: cat /proc/sys/vm/swappiness
- Посмотреть /proc/meminfo и /proc/zoneinfo
- Выполнить тестовую правку: sudo sysctl vm.swappiness=30
- Наблюдать метрики 24–72 часа
- Сделать постоянной в /etc/sysctl.conf при удовлетворительном результате
Короткое объявление (100–200 слов)
Swappiness — не порог, а регулятор приоритетов выгрузки страниц в Linux. Понимание того, что именно делает vm.swappiness, помогает администратору принимать более осознанные решения при тюнинге памяти. Изменение значения может помочь снизить swap churn на старых HDD или оптимизировать работу с файловым кэшем на системах с большим объёмом RAM, но любые правки следует тестировать на реплике рабочей нагрузки. Для большинства пользовательских систем сохранять значение по умолчанию — лучший выбор.
Итоговое резюме
Swappiness — это не «кнопка включения свопа». Это параметр, задающий отношение приоритетов между анонимными и file-backed страницами при сканировании и освобождении памяти. Реальные триггеры для сканирования определяются внутренними water marks зон и прочей логикой ядра. Перед изменением этого параметра собирайте метрики, тестируйте и применяйте изменения постепенно.
| | Команды Linux | | Files | tar · pv · cat · tac · chmod · grep · diff · sed · ar · man · pushd · popd · fsck · testdisk · seq · fd · pandoc · cd · $PATH · awk · join · jq · fold · uniq · journalctl · tail · stat · ls · fstab · echo · less · chgrp · chown · rev · look · strings · type · rename · zip · unzip · mount · umount · install · fdisk · mkfs · rm · rmdir · rsync · df · gpg · vi · nano · mkdir · du · ln · patch · convert · rclone · shred · srm · scp · gzip · chattr · cut · find · umask · wc · tr | | | Processes | alias · screen · top · nice · renice · progress · strace · systemd · tmux · chsh · history · at · batch · free · which · dmesg · chfn · usermod · ps · chroot · xargs · tty · pinky · lsof · vmstat · timeout · wall · yes · kill · sleep · sudo · su · time · groupadd · usermod · groups · lshw · shutdown · reboot · halt · poweroff · passwd · lscpu · crontab · date · bg · fg · pidof · nohup · pmap | | | Networking< | netstat · ping · traceroute · ip · ss · whois · fail2ban · bmon · dig · finger · nmap · ftp · curl · wget · who · whoami · w · iptables · ssh-keygen · ufw · arping · firewalld |
Похожие материалы
Безпарольный доступ к файлам в Windows Vista
Microsoft Editor: где найти и как использовать
Как поменять тему WordPress: 3 простых шага
Где купить лицензию Windows выгодно перед Windows 10
Вкладка «Разработчик» в Word и Excel — включение и применение