- Вопрос или проблема
- Некоторые советы и приемы
- Чтение вывода free
- Альтернатива с использованием /proc/meminfo вместо free
- Освобождение подкачки swapoff -a.
- О swapiness
- Использование vmstat 1
- Ответ или решение
- Как освободить место в свопе, если есть свободная ОЗУ
- Понимание свопа
- Основные команды для работы со свопом
- Проверка свободной памяти
- Изменение параметра swappiness
- Программный способ освобождения свопа
- Заключение
Вопрос или проблема
Когда я открываю ресурсоемкое приложение (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 МБ, и все системы работают плавно!
Параметр swappiness контролирует склонность ядра перемещать процессы из физической памяти на диск подкачки. Поскольку диски намного медленнее ОЗУ, это может привести к более медленным временем отклика для системы и приложений, если процессы слишком активно перемещаются из памяти.
- swappiness может иметь значение от 0 до 100
- swappiness=0 говорит ядру избегать перемещения процессов из физической памяти, пока это возможно
- 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:
sudoedit /etc/sysctl.conf
- Добавьте эту строку
vm.swappiness = 0
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 скрипт, основанный на 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 — это пространство на жестком диске, которое используется как временное хранилище для данных, которые в данный момент не помещаются в ОЗУ. Когда система активно использует своп, это может привести к замедлению работы, поскольку доступ к данным на жестком диске значительно медленнее, чем к данным в ОЗУ.
Основные команды для работы со свопом
Если вы хотите принудительно освободить своп, используйте следующие команды:
-
Отключение свопа:
sudo swapoff -a
Эта команда отключает все устройства свопа в системе.
-
Включение свопа:
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
позволяют обеспечить более эффективную работу приложений, особенно на системах с ограниченными ресурсами. Однако, если вы обнаружите, что своп не влияет на производительность, возможно, нет смысла в его освобождении. Дайте вашей системе работать оптимально и используйте своп только по необходимости.