Коли в Linux починає не вистачати оперативної пам’яті, система підвисає, а програми закриваються. Постійний великий swap‑розділ не завжди доречний: він займає місце на диску і зношує SSD. Краще зробити swap «розумним»: створювати його автоматично лише під час дефіциту RAM і видаляти, коли пам’яті знову достатньо. Саме це ми й реалізуємо за допомогою bash скрипти + cron та systemd timers — чиста автоматизація задач для оптимізація продуктивності 😺
Основний How‑to: динамічний swap через systemd + Bash
Крок 1. Створіть керуючий скрипт
Скрипт аналізує вільну пам’ять і за потреби створює або видаляє swap‑файл. Працює обережно: перевіряє місце на диску, права доступу та поточне використання swap.
#!/usr/bin/env bash
set -euo pipefail
# Конфіг
LOW_MEM_PCT=10 # нижче — створюємо swap
HIGH_MEM_PCT=30 # вище — намагаємось прибрати наш swap
MIN_DISK_FREE_MB=2048 # мінімум вільного місця на /, щоб створювати swap
SWAP_SIZE_MB=2048 # розмір одного авто-swap (2 ГБ)
SWAPFILE_DIR=/swap.d
SWAPFILE="$SWAPFILE_DIR/auto-swapfile.swap"
SWAP_PRIORITY=5
MAX_USED_KB_FOR_REMOVE=65536 # якщо наш swap зайнятий <= 64 МБ — можна вимкнути
LOG_TAG="auto-swap"
if [[ $EUID -ne 0 ]]; then echo "Run as root"; exit 1; fi
mkdir -p "$SWAPFILE_DIR" && chmod 700 "$SWAPFILE_DIR"
mem_total_kb=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
mem_avail_kb=$(awk '/MemAvailable/ {print $2}' /proc/meminfo)
mem_avail_pct=$(( mem_avail_kb * 100 / mem_total_kb ))
swap_total_kb=$(awk '/SwapTotal/ {print $2}' /proc/meminfo)
swap_free_kb=$(awk '/SwapFree/ {print $2}' /proc/meminfo)
swap_used_kb=$(( swap_total_kb - swap_free_kb ))
# Вільне місце на корені в КБ
root_free_kb=$(df -Pk / | awk 'NR==2{print $4}')
root_free_mb=$(( root_free_kb / 1024 ))
have_auto_swap() { swapon --noheadings --show=NAME | grep -q -- "$SWAPFILE"; }
used_kb_of_auto_swap() { awk -v f="$SWAPFILE" '$1==f {print $4}' /proc/swaps 2>/dev/null || echo 0; }
create_swap() {
logger -t "$LOG_TAG" "Creating swapfile $SWAPFILE size ${SWAP_SIZE_MB}M"
if ! fallocate -l ${SWAP_SIZE_MB}M "$SWAPFILE" 2>/dev/null; then
dd if=/dev/zero of="$SWAPFILE" bs=1M count=$SWAP_SIZE_MB status=none
fi
chmod 600 "$SWAPFILE"
mkswap "$SWAPFILE" >/dev/null
swapon -p "$SWAP_PRIORITY" "$SWAPFILE"
logger -t "$LOG_TAG" "Swapfile enabled"
}
remove_swap() {
logger -t "$LOG_TAG" "Trying to remove swapfile $SWAPFILE"
swapoff "$SWAPFILE"
rm -f "$SWAPFILE"
logger -t "$LOG_TAG" "Swapfile removed"
}
# Логіка прийняття рішень
if (( mem_avail_pct <= LOW_MEM_PCT )); then
if ! have_auto_swap; then
if (( root_free_mb >= MIN_DISK_FREE_MB + SWAP_SIZE_MB )); then
create_swap
else
logger -t "$LOG_TAG" "Not enough disk space to create swap (free ${root_free_mb}MB)"
fi
fi
elif (( mem_avail_pct >= HIGH_MEM_PCT )); then
if have_auto_swap; then
used_kb=$(used_kb_of_auto_swap)
if [[ -z "$used_kb" ]]; then used_kb=0; fi
if (( used_kb <= MAX_USED_KB_FOR_REMOVE )); then
remove_swap
else
logger -t "$LOG_TAG" "Swap in use (${used_kb}KB), postpone removal"
fi
fi
fi
Збережіть файл як:
sudo nano /usr/local/bin/auto-swap.sh
sudo chmod 700 /usr/local/bin/auto-swap.sh
Крок 2. Описуємо systemd service і timer
Щоб не плодити cron‑джоби, скористаємося cron та systemd timers саме у варіанті systemd: таймер раз на хвилину викликатиме наш сервіс.
# Сервіс
sudo tee /etc/systemd/system/auto-swap.service >/dev/null <<'EOF'
[Unit]
Description=Auto-manage swapfile on memory pressure
[Service]
Type=oneshot
ExecStart=/usr/local/bin/auto-swap.sh
Nice=10
EOF
# Таймер
sudo tee /etc/systemd/system/auto-swap.timer >/dev/null <<'EOF'
[Unit]
Description=Run auto-swap every minute
[Timer]
OnBootSec=2min
OnUnitActiveSec=1min
AccuracySec=10s
Unit=auto-swap.service
[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now auto-swap.timer
sudo systemctl status auto-swap.timer --no-pager
Крок 3. Перевірка роботи
Подивіться логи та активні swap‑пристрої:
journalctl -u auto-swap.service -n 50 --no-pager
swapon --show --bytes
free -h
Для штучного навантаження на RAM можна запустити важку збірку або відкрити багато вкладок у браузері. Також підійде короткий тест на Python (він виділить пам’ять і почекає):
python3 -c 'x=[bytearray(200*1024*1024) for _ in range(10)]; input()'
Альтернативні способи
- zram/zswap: стискання у RAM замість запису на диск. На десктопах часто дає кращу чутливість. Пакети: zram-tools (Debian/Ubuntu), systemd-zram-generator (інші).
- swapspace або systemd-swap: готові демони, що автоматично керують swap‑файлами. Зручні, якщо не хочете підтримувати власний скрипт.
- Статичний swap‑файл фіксованого розміру: простіше, але без «самовидалення».
GUI-спосіб (через Cockpit)
Якщо ви любите графіку, веб‑консоль Cockpit допоможе керувати службами та дивитися пам’ять у реальному часі. Встановіть, увімкніть і відкрийте у браузері https://localhost:9090, далі розділ «Services → Timers» для керування авто‑таймером, а у «Metrics/Usage» — моніторинг RAM і swap ⚙️
sudo apt install -y cockpit
sudo systemctl enable --now cockpit.socket
FAQ
Чи безпечно часто створювати/видаляти swap на SSD?
Нормально у помірних межах, але інтенсивний swap зношує SSD. Якщо ви часто впираєтесь у RAM, спробуйте zram або додайте оперативну пам’ять.
fallocate завершився з помилкою
Деякі ФС (особливо з CoW, наприклад Btrfs без NOCOW) можуть не підтримувати ефективний fallocate для swap. Скрипт має резервний шлях через dd. На Btrfs рекомендується створити файл у каталозі з вимкненим CoW (chattr +C) і без стиснення.
swapoff каже, що пристрій зайнятий
Значить, наш swap ще використовується. Скрипт видаляє файл лише коли зайнято менше 64 МБ. Можете підвищити HIGH_MEM_PCT або MAX_USED_KB_FOR_REMOVE, або просто зачекати, поки сторінки повернуться у RAM.
Таймер не запускається
Перевірте статус і журнали:
systemctl status auto-swap.timer auto-swap.service --no-pager
journalctl -u auto-swap.service -b --no-pager
sudo systemctl daemon-reload
sudo systemctl restart auto-swap.timer
Права доступу Linux: mkswap відмовляє
Переконайтеся, що файл має права 600 і що ви запускаєте від root:
sudo chmod 600 /swap.d/auto-swapfile.swap
sudo swapon /swap.d/auto-swapfile.swap
Чи можна підкрутити swappiness?
Так, іноді корисно знизити агресивність свопінгу:
echo 40 | sudo tee /proc/sys/vm/swappiness
# постійно через sysctl
echo 'vm.swappiness=40' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --system
Порада від Kernelka
Щоб не «стріляти собі в ногу», відрегулюйте пороги під вашу систему. На сервері з великим трафіком ставте нижчий LOW_MEM_PCT (5–8%), а на ноутбуці — вищий (10–15%). І тримайте відкритими інструменти моніторингу (htop, free, swapon) — так легше зрозуміти, коли спрацьовує автоматизація задач.
Підсумок
- Ми додали розумний механізм створення/видалення swap‑файла при дефіциті RAM.
- Використали чисті bash скрипти та systemd timer без зайвих залежностей.
- Скрипт перевіряє права, місце на диску та безпечно зупиняє swap.
- Показали альтернативи: zram/zswap, готові демони, статичний swap.
- Налаштування гнучке: змінюйте пороги, розмір і пріоритет під ваші навантаження.

Прокоментувати
На сайті відображається лише твоє ім'я та коментар. Електронна пошта зберігається виключно для зв'язку з тобою за потреби та в жодному разі не передається стороннім особам.