Как освободить своп, если есть свободная RAM?

Вопрос или проблема

Когда я открываю ресурсоемкое приложение (VirtualBox, установленное на 2 ГБ ОЗУ), используется некоторое пространство подкачки, в зависимости от того, что еще у меня открыто в данный момент.

Однако, когда я закрываю это последнее приложение, 2 ГБ ОЗУ освобождаются, но использование пространства подкачки остается таким же.

Например, сейчас, через два часа после закрытия VirtualBox, у меня 1.6 ГБ свободной ОЗУ и все еще 770 МБ в подкачке.

Как я могу сказать Ubuntu перестать использовать эту подкачку и вернуться к использованию ОЗУ?

Ядро Linux, лежащее в основе Ubuntu, автоматически “переключает” эти страницы с диска на ОЗУ по мере необходимости, поэтому, в общем, я бы сказал, просто дайте этому происходить естественным образом.

Тем не менее, если вы действительно считаете, что вам нужно заставить это, (я вижу сценарий, когда вы хотите знать, что система будет отзывчивой позже) вы можете временно отключить и снова включить подкачку

sudo swapoff -a
sudo swapon -a

ИЛИ, альтернативно, как одна строка

sudo swapoff -a; sudo swapon -a

Будьте осторожны, делая это, так как вы можете сделать вашу систему нестабильной, особенно если у вас уже мало ОЗУ. Убедитесь, что у вас достаточно свободной ОЗУ в системе, иначе вы можете не смочь освободить подкачку, и OOM-Killer в конечном итоге убьет некоторые ваши процессы.

Обратите внимание, что swapoff может занять некоторое время. Это в особенности верно, если у вас много подкачки для отключения.

Только потому, что подкачка выделена, не означает, что она “используется”. Хотя такие программы, как системный монитор и top, покажут, что часть вашего пространства подкачки выделена (в вашем примере 770 МБ), это не означает, что система активно переключает данные.

Чтобы выяснить, что-то ли действительно переключается, вы можете использовать команду vmstat. Оставьте ее работать несколько секунд, чтобы успокоиться, и посмотрите на колонки si (подкачка) и so (выгрузка). Если ничего не происходит, значит, нет причины беспокоиться.

Вот вывод при выполнении vmstat 1, где вы можете видеть, что моя машина вообще не переключает.

procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 0  0  78588 230788   9596  72196    0    0     0     0  543  652 12  6 78  0
 0  0  78588 230780   9596  72196    0    0     0     0  531  410  1  0 99  0
 0  0  78588 230796   9596  72196    0    0     0     0  300  335  1  1 97  0
 1  0  78588 230788   9608  72224    0    0    40     0  737  762  4  4 84  8
 5  0  78588 230788   9608  72224    0    0     0     0  415  385  9  3 84  0
 0  0  78588 230540   9616  72224    0    0     0    44  611  556 55  5 31  0
 0  0  78588 230532   9616  72224    0    0     0     0  574  662  1  6 89  0

Тем не менее, здесь в top вы можете видеть, что у меня выделено пространство подкачки:

Mem:    475236k total,   245076k used,   230160k free,     9720k buffers
Swap:   491512k total,    78588k used,   412924k free,    72476k cached

Вы также можете установить значение “swappiness” по умолчанию 60, таким образом, подкачка не будет увеличиваться настолько много с самого начала. Почему параметр по умолчанию установлен на 60, когда рекомендованное значение 10, меня озадачивает. Согласно Ubuntu SwapFAQ:

Настройка по умолчанию в Ubuntu – swappiness=60. Снижение значения swappiness, вероятно, улучшит общую производительность для типичной настольной установки Ubuntu. Рекомендуется значение swappiness=10, но не стесняйтесь экспериментировать.

Изменив это значение на 10 или даже 0, вы можете существенно увеличить и ощутить прирост производительности на старой системе с медленным диском. Установка этого значения на 0 не отключает подкачку для ядра Linux 3.4 и ниже, но с 3.5+ это делает, так что вам захочется использовать значение 1, если вы хотите оставить его на самом низком уровне*.

Я не вижу причин, чтобы не установить это на 0, так как все, что попадает на диск, медленнее, чем ОЗУ. У меня 8 виртуальных ядер, быстрый SSD и 8 ГБ памяти, и моя подкачка установлена на 0. В данный момент у меня работают 3 виртуальные машины, использование памяти составляет 7.1 из 7.7 ГБ, моя используемая подкачка составляет всего 576 КБ из 952 МБ, и все системы работают плавно!

Согласно Ubuntu SwapFAQ:

Параметр swappiness контролирует склонность ядра перемещать процессы из физической памяти на диск подкачки. Поскольку диски намного медленнее ОЗУ, это может привести к более медленным временем отклика для системы и приложений, если процессы слишком активно перемещаются из памяти.

  1. swappiness может иметь значение от 0 до 100
  2. swappiness=0 говорит ядру избегать перемещения процессов из физической памяти, пока это возможно
  3. swappiness=100 говорит ядру активно перемещать процессы из физической памяти и перемещать их в кэш подкачки

Ниже приведены основные инструкции по проверке swappiness, освобождению вашей подкачки и изменению swappiness на 0:

Чтобы проверить значение swappiness:

cat /proc/sys/vm/swappiness

Чтобы временно установить подкачку на 0 (как предложил SpamapS):

Это освободит вашу подкачку и перенесет всю подкачку обратно в память. Сначала убедитесь, что у вас достаточно доступной памяти, просмотрев вкладку ресурсов в gnome-system-monitor, ваша свободная память должна быть больше вашей используемой подкачки. Этот процесс может занять некоторое время, используйте gnome-system-monitor для мониторинга и проверки прогресса.

sudo swapoff --all

Чтобы установить новое значение на 0:

sudo sysctl vm.swappiness=0 

Чтобы снова включить подкачку:

sudo swapon --all

Чтобы навсегда установить swappiness на 0:

  1. sudoedit /etc/sysctl.conf
  2. Добавьте эту строку vm.swappiness = 0
  3. sudo shutdown -r now # перезагрузить систему

* С версией ядра 3.5+ установка swappiness на 0 действительно полностью отключает его, и рекомендуется установить значение 1, если вы хотите использовать алгоритм с наименьшей подкачкой. источник: https://www.percona.com/blog/2014/04/28/oom-relation-vm-swappiness0-new-kernel/

Я обнаружил, что освобождение подкачки может сильно помочь на системах с медленными дисками и ограниченной ОЗУ. Конечно, как уже упоминалось, сделать это можно, выполнив sudo swapoff -a; sudo swapon -a. Проблема в том, что если ОЗУ недостаточно, это вызовет различные проблемы.

Я написал скрипт, который я называю toggle_swap, который работал для меня последние несколько лет. Он проверяет наличие достаточного количества свободной ОЗУ перед фактическим отключением подкачки. Вот он:

#!/bin/bash

free_data="$(free)"
mem_data="$(echo "$free_data" | grep 'Mem:')"
free_mem="$(echo "$mem_data" | awk '{print $4}')"
buffers="$(echo "$mem_data" | awk '{print $6}')"
cache="$(echo "$mem_data" | awk '{print $7}')"
total_free=$((free_mem + buffers + cache))
used_swap="$(echo "$free_data" | grep 'Swap:' | awk '{print $3}')"

echo -e "Свободная память:\t$total_free kB ($((total_free / 1024)) MB)\nИспользуемая подкачка:\t$used_swap kB ($((used_swap / 1024)) MB)"
if [[ $used_swap -eq 0 ]]; then
    echo "Поздравляю! Подкачка не используется."
elif [[ $used_swap -lt $total_free ]]; then
    echo "Освобождение подкачки..."
    sudo swapoff -a
    sudo swapon -a
else
    echo "Недостаточно свободной памяти. Выход."
    exit 1
fi

После нескольких дней экспериментов с swappiness, я пришел к выводу, что ядро должно быть оставлено самим себе. Оно знает, что делает, и оптимизировано для того, чтобы предоставить вам лучший опыт.

Если у вас нет действительно хорошей причины для того, чтобы вернуть этот диск, я бы оставил его в покое.

Новый ответ 2023!

Некоторые советы и приемы

Помимо всех существующих ответов, я хочу поделиться некоторыми приемами, которые я использую.

Чтение вывода free

Сначала убедитесь, что вывод free не локализован, для этого вам нужно предварить команду LANG=C free -k:

               total        used        free      shared  buff/cache   available
Mem:        32739720     9436264     8704992      883044    15959152    23303456
Swap:       23437308     5450752    17986556

Где, если вы посчитаете buff/cache + available, результат будет больше, чем total! Это неверно!!

Просто учтите, что available mem больше, чем used swap, прежде чем освобождать подкачку!

msgs=("NOT " "")
{ # считываем вывод `free`, игнорируем 1-ю строку и все значения, кроме свободной и используемой подкачки.
    read _
    read -r _{,,,,,} avail
    read -r _ _ swaped _
} < <(LANG=C free -k)
printf 'Доступно: %d подкачки: %d Могу %sосвободить подкачку!\n' \
           "$avail" "$swaped" "${msgs[ avail > swaped ]}"
 Доступно: 23303456 подкачки: 5450752 Могу освободить подкачку!

Альтернатива с использованием /proc/meminfo вместо free

Обращаясь напрямую к /proc/meminfo вместо выполнения fork к free, вы могли бы получить такие же значения с помощью:

msgs=("NOT " "")
while read field val _; do
    case $field in
        MemAvailable: ) avail=$val ;;
        SwapTotal: )    declare -i swaped=$val ;;
        SwapFree: )     swaped+=-$val; break ;;
    esac
done < /proc/meminfo
printf 'Доступно: %d подкачки: %d Могу %sосвободить подкачку!\n' \
           "$avail" "$swaped" "${msgs[ avail > swaped ]}"
 Доступно: 23303456 подкачки: 5450752 Могу освободить подкачку!

Освобождение подкачки swapoff -a.

Я создал небольшой скрипт, который

  • правильно анализирует вывод free,
  • показывает удобочитаемые используемые и доступные памяти,
  • предлагает выполнить цикл swapoff - swapon, если пользователь не взаимодействует
  • а затем вычисляет время, потраченное на освобождение подкачки.

Вот мой скрипт, основанный на bash V>5.0:

#!/bin/bash

msgs=("NOT " "")
while read field val _; do
    case $field in
        MemAvailable: ) avail=$val ;;
        SwapTotal: )    declare -i swaped=$val ;;
        SwapFree: )     swaped+=-$val; break ;;
    esac
done < /proc/meminfo

txtsize() { # Преобразовать целое число в удобочитаемую строку, сохранить результат в переменной $2
    local i=$(($1>=1<<50?5:$1>=1<<40?4:$1>=1<<30?3:$1>=1<<20?2:$1>1023?1:0))
    local a=(K M G T P)
    ((i>4?i+=-2:0)) && a=(${a[@]:2}) && set -- $(($1>>20)) $2
    local r=00$((1000*$1/(1024**i)))
    printf -v $2 %.2f%s ${r::-3}.${r: -3} ${a[i]}
}

txtsize $avail havail
txtsize $swaped hswaped
printf 'Доступно: %s (%d) подкачки: (%s) %d Могу %sосвободить подкачку!\n' \
    "$havail" $avail "$hswaped" $swaped "${msgs[ avail > swaped ]}"
if (( avail > swaped )); then
    if read -sn 1 -t 5 -p\
        'Продолжить через 5 секунд. Нажмите любую клавишу для остановки. '; then
        echo $'\nПрерывание пользователем.'
            exit 0
    fi
    echo
    elapsedTime=${EPOCHREALTIME/.}
    swapoff -a
    elapsedTime=00000$(( ${EPOCHREALTIME/.} - elapsedTime ))
    swapon -a
    elapsedMin=$(( 10#$elapsedTime / 60000000 ))
    elapsedSec=00000$(( 10#$elapsedTime % 60000000 ))
    printf 'Подкачка: %s освобождена за %d минут и %.3f секунды (%.4f").\n' \
        "$hswaped" "$elapsedMin" ${elapsedSec::-6}.${elapsedSec: -6} \
        ${elapsedTime::-6}.${elapsedTime: -6}

fi    

Результат выглядит так:

Доступно: 23.86G (25023596) подкачки: (1.14G) 1192460 Могу освободить подкачку!
Продолжить через 5 секунд. Нажмите любую клавишу для остановки. 
Подкачка: 1.14G освобождена за 1 минуту и 51.166 секунд (111.1661").

Этот скрипт требует root привилегий. Но вы можете отредактировать его, добавив sudo перед swapoff -a и swapon -a.

С тех пор, поскольку эта операция может занять некоторое время, я создал полный скрипт purgeSwap, показывающий прогресс с помощью красивой индикаторной полосы и вычисляющий оценку времени окончания, вы можете скачать его здесь: 👉 purgeSwap.sh.

Этот ответ связан с этим другим: Как узнать, какие процессы используют пространство подкачки в Linux?

О swapiness

Я не совсем уверен, как это вычисляет процент используемой памяти: включает подкачку или нет… Для моих тестов я заметил много подкачки перед достижением процентов, настроенных в этой переменной ядра.

Тем не менее, для моих серверов я все еще использую:

echo 10 > /proc/sys/vm/swappiness

для работающей системы, которая еще не была настроена:

echo >/etc/sysctl.d/90-swappiness.conf  'vm.swappiness = 10'

перед последней перезагрузкой.

Использование vmstat 1

Я часто использую это, но так как мне нравится графическое представление, я создал (в 2009 году) перл CGI, который мог работать в самостоятельном режиме:

http://perso.f-hauri.ch/~felix/marcm/vmstat.cgi

Этот скрипт можно скачать самостоятельно, он работает на любом веб-сервере, но может использоваться непосредственно на бедных системах. Графика рисуется в svg и отображается вашим браузером.

Пример использования:

wget -O vmstat.pl http://perso.f-hauri.ch/~felix/marcm/vmstat.cgi/download/vmstat.cgi
LANG=C perl vmstat.pl 
CGI::Pretty устарел и будет удален в будущих выпусках. Пожалуйста, смотрите https://github.com/leejo/CGI.pm/issues/162 для получения дополнительной информации в /usr/share/perl5/CGI/Pretty.pm строка 20.
Сервер запущен на порту 8881

Да, это старый скрипт не выполняйте его от имени root!!.

…Затем вы можете подключиться с помощью браузера:

http://ip.add.re.ss:8881/

http://127.0.0.1:8881/?delay=1&width=1800&height=120

Здесь 1’800 точек с задержкой в 1 секунду создают графики за полчаса.

Скажите виртуальной машине, чтобы она не использовала подкачку так часто, уменьшив swappiness, с помощью

sudo sysctl vm.swappiness=10

или даже не использовала подкачку как можно меньше, с помощью

sudo sysctl vm.swappiness=0

Пожалуйста, прочитайте документацию о swapfile здесь:
https://help.ubuntu.com/community/SwapFaq

Это не влияет на производительность, если ваше пространство подкачки занято. Единственное снижение производительности происходит, когда данные попадают в/из подкачки. Если ничего не подкачивается, то вам не о чем беспокоиться.

Ответ или решение

Как освободить место в свопе, если есть свободная ОЗУ

При использовании приложений, требующих значительного объема оперативной памяти (ОЗУ), таких как VirtualBox, система может начать использовать пространство свопа на диске. Даже после того, как приложение закрыто и ОЗУ снова стало доступно, место в свопе может оставаться занятым. В данном руководстве мы подробно рассмотрим, как освободить своп и вернуть его использование исключительно ОЗУ.

Понимание свопа

Прежде чем переходить к действиям, важно понимать, что своп в Linux — это пространство на жестком диске, которое используется как временное хранилище для данных, которые в данный момент не помещаются в ОЗУ. Когда система активно использует своп, это может привести к замедлению работы, поскольку доступ к данным на жестком диске значительно медленнее, чем к данным в ОЗУ.

Основные команды для работы со свопом

Если вы хотите принудительно освободить своп, используйте следующие команды:

  1. Отключение свопа:

    sudo swapoff -a

    Эта команда отключает все устройства свопа в системе.

  2. Включение свопа:

    sudo swapon -a

    Эта команда снова активирует своп.

Существует возможность выполнить обе команды одной строкой:

sudo swapoff -a; sudo swapon -a

Проверка свободной памяти

Прежде чем отключить своп, убедитесь, что у вас достаточно свободной ОЗУ. Вы можете использовать команду free -k для проверки текущего состояния памяти:

free -k

Обратите внимание на значения в столбце "available", чтобы убедиться, что свободной памяти достаточно для освобождения свопа.

Изменение параметра swappiness

Параметр swappiness определяет, как часто система перемещает данные из ОЗУ в своп. По умолчанию этот параметр установлен на 60, что может быть слишком высоким для рабочих станций. Чтобы изменить его значение, используйте команду:

sudo sysctl vm.swappiness=10

Для временного изменения параметра нужно использовать вышеуказанную команду. Чтобы сделать изменение постоянным, откройте файл конфигурации:

sudo nano /etc/sysctl.conf

Добавьте строку:

vm.swappiness=10

Затем сохраните файл и перезагрузите систему.

Программный способ освобождения свопа

Для тех, кто часто работает с освобождением свопа, также хорошо иметь скрипт. Например, вы можете создать скрипт, который будет проверять наличие достаточного объема ОЗУ перед отключением свопа. Пример скрипта:

#!/bin/bash
free_data="$(free)"
mem_data="$(echo "$free_data" | grep 'Mem:')"
free_mem="$(echo "$mem_data" | awk '{print $4}')"
buffers="$(echo "$mem_data" | awk '{print $6}')"
cache="$(echo "$mem_data" | awk '{print $7}')"
total_free=$((free_mem + buffers + cache))
used_swap="$(echo "$free_data" | grep 'Swap:' | awk '{print $3}')"

if [[ $used_swap -eq 0 ]]; then
    echo "Замечательно! Своп не используется."
elif [[ $used_swap -lt $total_free ]]; then
    echo "Освобождение свопа..."
    sudo swapoff -a
    sudo swapon -a
else
    echo "Недостаточно свободной памяти. Выход."
    exit 1
fi

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...