Файл подкачки и виртуальная память: как работает swap в Windows и Linux

Файл подкачки и виртуальная память: как работает swap в Windows и Linux Полезное

Файл подкачки (swap, своп) — это область на диске, куда операционная система временно переносит страницы памяти, которым сейчас не хватило места в оперативной памяти (ОЗУ). Он не ускоряет ОЗУ и не заменяет ее — это запасное, более медленное хранилище под редко используемые данные.

Тему часто путают, потому что тремя разными понятиями пользуются как синонимами. Разведем их сразу — дальше по тексту различие важно.

  • Виртуальная память — модель, при которой каждая программа работает со своим адресным пространством, а система сама решает, где физически лежат данные: в ОЗУ или на диске.
  • Страничная организация (paging) — деление памяти на блоки фиксированного размера (страницы) и отображение виртуальных страниц на физические кадры ОЗУ.
  • Вытеснение страниц (swapping, paging out) — перенос страниц из ОЗУ на диск, когда физической памяти не хватает, и загрузка обратно, когда они снова нужны.
  • Файл или раздел подкачки — конкретное место на диске под вытесненные страницы: pagefile.sys в Windows, swap-раздел или swap-файл в Linux.

Ключевое различие: виртуальная память есть всегда, даже когда файл подкачки выключен — система в любом случае работает с виртуальными адресами. Файл подкачки — лишь одно из мест, куда она складывает данные, не поместившиеся в ОЗУ.

Как работает страничная подкачка

Проследим на одном сквозном примере. Пусть программе нужно 10 ГБ данных, а физической ОЗУ — 8 ГБ. Без виртуальной памяти программа бы не запустилась. С ней происходит следующая цепочка.

  1. Программа обращается к данным по виртуальному адресу — своему, независимому от физического расположения.
  2. Процессор и ядро переводят виртуальный адрес в номер страницы.
  3. Страница либо уже лежит в кадре ОЗУ (тогда доступ мгновенный), либо была вытеснена в файл подкачки.
  4. Если страница на диске, возникает page fault: ядро находит редко используемую страницу в ОЗУ, при необходимости вытесняет ее в своп и подгружает нужную страницу с диска на освободившийся кадр.

Итог цепочки: виртуальный адрес -> страница -> кадр в ОЗУ или блок в файле подкачки. Пока в свопе оседают действительно холодные данные, пользователь замедления не замечает. Проблемы начинаются, когда активных данных становится больше, чем ОЗУ: диск в разы медленнее памяти даже на NVMe SSD, поэтому своп — страховка от аварийного завершения, а не расширение объема быстрой памяти (см. раздел про thrashing).

Файл подкачки в Windows

В Windows своп реализован файлом pagefile.sys в корне системного диска. Обычно система управляет им автоматически (галочка «Автоматически выбирать объем файла подкачки»), и в большинстве случаев это оптимальный выбор.

Рядом может лежать swapfile.sys — отдельный файл для приостановки приложений из Microsoft Store (UWP). Это не то же самое, что pagefile.sys, и трогать его вручную не нужно. А режим гибернации в Windows пишет память в третий файл — hiberfil.sys, тоже отдельный от файла подкачки.

Настройки открываются так:

  1. Нажать Win + R, ввести sysdm.cpl, подтвердить.
  2. Вкладка «Дополнительно» -> «Быстродействие» -> «Параметры».
  3. Вкладка «Дополнительно» -> «Виртуальная память» -> «Изменить».
  4. Снять «Автоматически выбирать объем файла подкачки», выбрать диск, задать «Исходный размер» и «Максимальный размер» в мегабайтах, нажать «Задать».

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

Файл подкачки в Linux

В Linux своп бывает двух видов: отдельный раздел подкачки или swap-файл внутри обычной файловой системы. По производительности на современных ядрах они практически равны; файл гибче — его проще создать и изменить без переразбивки диска.

Сначала проверим, есть ли своп сейчас:

# Показать активные области подкачки (пусто = свопа нет)
swapon --show
# Строка Swap покажет общий объем и занятое
free -h

Пример вывода free -h (значения зависят от системы):

               total        used        free      shared  buff/cache   available
Mem:            15Gi       6.2Gi       1.1Gi       0.5Gi       8.1Gi       8.3Gi
Swap:          4.0Gi       128Mi       3.9Gi

Создадим swap-файл на 4 ГБ. Надежный универсальный способ — dd: он записывает реальные нули, и файл гарантированно без «дыр».

# Проверяем свободное место на диске
df -h
# Создаем файл 4 ГБ: 4096 блоков по 1 МБ
sudo dd if=/dev/zero of=/swapfile bs=1M count=4096 status=progress
# Доступ только root: обязательное требование, иначе swapon предупредит
sudo chmod 600 /swapfile
# Размечаем файл как область подкачки
sudo mkswap /swapfile
# Подключаем прямо сейчас
sudo swapon /swapfile
# Проверяем
swapon --show

Ожидаемый результат swapon --show:

NAME      TYPE  SIZE USED PRIO
/swapfile file    4G   0B   -2

Быстрая альтернатива dd — fallocate -l 4G /swapfile. Она мгновенна на ext4, но на некоторых файловых системах (например, Btrfs без отдельной подготовки) swapon откажется подключать такой файл с ошибкой про holes. Если сомневаетесь — берите dd.

Чтобы своп подключался после перезагрузки, добавьте его в /etc/fstab:

# Строка сработает при следующей загрузке
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Параметр swappiness

vm.swappiness управляет тем, насколько охотно ядро вытесняет анонимные страницы (кучу и стек процессов) в своп, вместо того чтобы освобождать страничный кэш. Значение по умолчанию во многих дистрибутивах — 60, диапазон 0-100 (в ядрах начиная с 5.8 верхняя граница поднята до 200).

# Текущее значение
cat /proc/sys/vm/swappiness
# Временно снизить до 10 (до перезагрузки)
sudo sysctl vm.swappiness=10
# Закрепить постоянно
echo 'vm.swappiness=10' | sudo tee /etc/sysctl.d/99-swappiness.conf

Меньшее значение не отключает своп совсем — даже при swappiness=0 ядро воспользуется свопом при реальной угрозе нехватки памяти. Оно лишь сдвигает баланс в сторону удержания процессов в ОЗУ. На десктопе с достаточной ОЗУ значения 10-20 часто дают более отзывчивую систему; на сервере ориентируйтесь на профиль нагрузки, а не на «правильную» цифру.

Отдельно стоит упомянуть zram и zswap — сжатый своп. zram создает сжатое блочное устройство прямо в ОЗУ и использует его как приоритетную область подкачки; часть современных дистрибутивов включает его по умолчанию. Это компромисс между скоростью ОЗУ и объемом, полезный на машинах с малым объемом памяти.

Когда своп помогает, а когда тормозит

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

Ситуация Что делает своп Итог
Кратковременный пик потребления памяти Принимает лишние страницы, процесс не падает Помогает
Долго неактивная фоновая программа Ее страницы уходят на диск, ОЗУ освобождается под кэш Помогает
Активных данных больше, чем ОЗУ Страницы гоняются ОЗУ <-> диск без остановки Тормозит (thrashing)
Нехватка ОЗУ при выключенном свопе Срабатывает OOM killer, процесс завершается Своп бы смягчил

Swap thrashing (пробуксовка) — состояние, когда рабочий набор активных страниц не помещается в ОЗУ, и система тратит почти все время на подкачку вместо полезной работы. Симптомы: система почти не отвечает, диск загружен на 100%, а загрузка процессора низкая. Диагностировать помогает vmstat:

# Колонки si (swap in) и so (swap out) в КБ/с
vmstat 1

Если si и so стабильно большие несколько секунд подряд — это пробуксовка. Лечение тут не в увеличении свопа (это лишь оттянет момент), а в добавлении ОЗУ или снижении потребления памяти. Своп спасает от аварийного завершения, но не превращает медленный диск в быструю память.

Нужен ли своп при большом объеме ОЗУ

Короткий ответ: небольшой своп полезен почти всегда, но его роль меняется. Даже при 32-64 ГБ ОЗУ немного свопа позволяет ядру выгрузить страницы, которые не использовались часами, и отдать освободившуюся ОЗУ под файловый кэш. Полностью отключать своп имеет смысл разве что на специфичных серверах с жестким контролем памяти (например, узлы Kubernetes, где своп исторически отключали намеренно).

Есть и обязательный случай: гибернация. В Linux образ памяти при уходе в спящий режим пишется в своп, поэтому для гибернации своп должен быть не меньше объема ОЗУ. В Windows гибернация использует отдельный hiberfil.sys, а не файл подкачки.

Про миф «swap = 2x RAM» и износ SSD

Правило «размер свопа = удвоенный объем ОЗУ» родилось в эпоху, когда ОЗУ измерялась мегабайтами. Сегодня для машины с 32 ГБ ОЗУ оно означало бы 64 ГБ свопа — это трата места без пользы: столько активных данных на диск все равно не выгрузить с приемлемой скоростью. Правило устарело, привязывать размер свопа к ОЗУ линейно больше не нужно.

Ориентировочные рекомендации (например, из гайдов Red Hat) выглядят так — это отправная точка, а не жесткая норма, уточняйте под свою нагрузку:

ОЗУ Своп без гибернации Своп с гибернацией
до 2 ГБ 2 x ОЗУ 3 x ОЗУ
2-8 ГБ равен ОЗУ 2 x ОЗУ
8-64 ГБ от 4 ГБ 1.5 x ОЗУ
больше 64 ГБ от 4 ГБ по нагрузке гибернация не рекомендуется

Опасение «своп убьет SSD» тоже во многом устарело. Ресурс записи современных потребительских SSD — сотни терабайт (TBW), а нормально настроенная система пишет в своп немного, потому что вытесняет именно холодные страницы. При пробуксовке износ действительно растет, но корень проблемы — нехватка ОЗУ, и решать надо ее, а не переносить своп ради экономии диска. Своп на SSD дает и плюс: подкачка с него в разы быстрее, чем с HDD, а TRIM для swap-раздела поддерживается.

Выводы

  • Виртуальная память, страничная подкачка и файл подкачки — три разных понятия: модель адресации, механизм перемещения страниц и место на диске соответственно.
  • Своп — страховка от нехватки ОЗУ и способ выгрузить холодные страницы, но не расширение быстрой памяти: диск в разы медленнее ОЗУ.
  • В Windows своп — это pagefile.sys (автоуправление обычно лучше ручного); в Linux — swap-раздел или swap-файл, поведение регулирует vm.swappiness.
  • Постоянная активность свопа (si/so в vmstat) — это thrashing, признак нехватки ОЗУ; лечится добавлением памяти, а не увеличением свопа.
  • Правило «swap = 2x RAM» устарело; размер подбирают по задаче, а для гибернации в Linux своп должен быть не меньше ОЗУ.

Где применяется / связь с практикой

Понимание виртуальной памяти и подкачки — базовый навык для тех, кто работает близко к операционной системе: пишет высоконагруженные сервисы, драйверы, встраиваемый софт или профилирует потребление памяти. Здесь важно видеть, как приложение отображается на страницы, когда происходит page fault и почему один и тот же код на машине с меньшей ОЗУ начинает пробуксовывать.

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

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

Смежные темы: Файлы и пути к ним.

FAQ

Можно ли перенести файл подкачки на другой диск?
Да. В Windows это делается в том же окне «Виртуальная память»: отключить подкачку на системном диске и включить на другом. В Linux достаточно создать swap-файл или раздел на нужном диске и прописать его в /etc/fstab. Перенос свопа на быстрый SSD с медленного HDD ускоряет подкачку.

Что произойдет, если полностью удалить своп?
Система продолжит работать, пока хватает ОЗУ. При исчерпании памяти без свопа сработает OOM killer и завершит один из процессов; в Linux также станет невозможна гибернация, а в Windows — запись полного дампа при сбое.

Почему при свободной ОЗУ часть данных все равно в свопе?
Ядро не возвращает страницы из свопа в ОЗУ автоматически сразу после освобождения памяти — они подгружаются обратно только при обращении. Это нормально и не является проблемой; принудительно очистить своп можно командой swapoff -a && swapon -a при наличии достаточной свободной ОЗУ.

OTUS Журнал