Как Linux освобождает заполненную память
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Механизм освобождения памяти в Linux
Linux управляет памятью через сложную иерархическую систему кэширования и подкачки, где "заполненная память" часто означает не дефицит, а активное использование ядром для повышения производительности. Освобождение происходит автоматически, но имеет несколько уровней приоритета.
1. Уровни памяти и понятие "свободной" памяти
В Linux память делится на:
- Анонимные страницы (Anonymous pages) — память процессов (куча, стек), не привязанная к файлам.
- Кэш страниц (Page Cache) — кэшированные данные файловых систем.
- Buffer Cache — кэшированные метаданные и сырые данные блочных устройств.
- Slab Cache — кэшированные объекты ядра (иноды, дескрипторы и т.д.).
Команда free -m показывает:
$ free -m
total used free shared buff/cache available
Mem: 7982 1500 300 200 6182 5800
Swap: 2048 0 2048
Здесь buff/cache — это "заполненная" память, которую система может быстро освободить. Ключевой показатель — available, который включает свободную память + легко освобождаемый кэш.
2. Алгоритмы освобождения памяти
А. Активное освобождение кэша (Page Cache)
При нехватке памяти (low memory) ядро Linux активирует механизм kswapd — фоновый демон, который:
- Сканирует списки LRU (Least Recently Used) для нахождения наименее используемых страниц.
- Освобождает "холодные" страницы Page Cache (которые не использовались давно).
- Если страница была изменена (dirty), сначала записывает её на диск через pdflush.
Пример принудительного освобождения кэша (для тестирования):
# Освобождает Page Cache, dentries и inodes
sudo sysctl vm.drop_caches=3
Важно: Это только для тестов, в работе система управляет этим автоматически.
Б. Подкачка (Swapping)
Если кэша недостаточно, система начинает свопировать анонимные страницы:
- Активные страницы процессов перемещаются в swap-область (дисковое пространство).
- Для управления используется алгоритм LRU с учётом активности страниц.
- Современные ядра используют Swappiness (
vm.swappiness) для баланса:
# Проверка текущего значения (0-100)
cat /proc/sys/vm/swappiness
# Уменьшение склонности к свопингу
sudo sysctl vm.swappiness=10
В. OOM Killer (Out-Of-Memory Killer)
При критической нехватке памяти ядро активирует OOM Killer, который:
- Вычисляет oom_score для каждого процесса (на основе использования памяти, приоритета и т.д.).
- Принудительно завершает процесс с наибольшим счётом.
- Можно настроить через
/proc/<pid>/oom_score_adj.
3. Стратегии освобождения в современных ядрах
Ядро Linux 5.x+ использует усовершенствованные механизмы:
- Pressure Stall Information (PSI) — отслеживает нехватку памяти в реальном времени.
- cgroups v2 — позволяет ограничивать и контролировать использование памяти на уровне контейнеров.
- Transparent Huge Pages (THP) — автоматическое управление огромными страницами, что влияет на фрагментацию и скорость освобождения.
4. Практический пример: мониторинг освобождения памяти
# Динамическое отслеживание освобождения памяти
watch -n1 "grep -e MemFree -e Dirty -e Writeback /proc/meminfo"
# Использование slabtop для мониторинга кэша ядра
sudo slabtop -s c
# Логирование действий kswapd и OOM Killer
sudo dmesg -T | grep -E "oom-killer|kswapd"
5. Оптимизация для DevOps-инфраструктуры
В контейнеризированных средах (Docker/Kubernetes):
- Memory Limits в cgroups автоматически инициируют освобождение.
- Kubernetes использует QoS классов (Guaranteed, Burstable, BestEffort) для управления приоритетами.
- Рекомендуется настройка swappiness=0 для контейнеров и использование swap только если необходимо.
Вывод: Linux освобождает память через многоуровневую систему, где приоритет отдаётся освобождению кэша, затем свопингу и, в крайнем случае, OOM Killer. Для DevOps важно понимать эти механизмы для настройки мониторинга и оптимизации памяти в распределённых системах.