28 Июл 2020 18:07:11 | 2 комментария
Как быстро выяснить какой процесс в Linux использует пространство подкачки (swap)
Заметка очень короткая и призвана администраторам помочь быстро найти процессы которые максимально используют пространство swap. Что делать с этими процессами — это уже отдельная тема, главное найти кто потребляет swap.
Исходные данные: ОС Oracle Linux 7;
Задач: Найти потребителя SWAP
Типичная ситуация на сервере с системой мониторинга — это аларм вида:
prod-srv-01 Low free swap space (free: 0.15 %, threshold: 10%, alert started: 8.79 %)
Вначале немного теории, о том как получить информацию о распределении памяти процессами в Linux.
Мы видим, что swap заполнен на 100% — это плохо. Попробуем быстро выяснить кто основной потребитель, для этого обратимся к /proc/*/status
Ниже простой сценарий на bash который выдаст нам список потребителей swap:
for file in /proc/*/status ; do awk '/VmSwap|Name/END< print "">' $file; done | sort -k 2 -n -r | less
Мы видим, что основной потребитель — это процесс ora_j001_bs. На сервере установлен Oracle и один из процессов потребляет swap.
На втором месте мы видим процесс rsyslogd — думаю он в представлении не нуждается. Если на потребителя №1 мы не можем повлиять быстро, то на потребителя №2 (rsyslogd) можем — это попытаться его перазапустить. Выполняем перезапуск rsyslogd:
systemctl restart rsyslog
[[email protected] ~]# free -h total used free shared buff/cache available Mem: 15G 2.8G 301M 5.6G 12G 6.9G Swap: 5.0G 3.4G 1.6G
Мы видим, что стало доступно 1.6 GB, а это уже более 30% от размера swap, что вполне нас должно устроить на первое время. На этом все, до скорых встреч. Если у Вас возникли вопросы или Вы хотите чтобы я помог Вам, то Вы всегда можете связаться со мной разными доступными способами.
Какие процессы заняли SWAP в Unix/Linux
Утилиты top/htop и free отображают общее количество свободной, занятой физической памяти, а так же SWAP на сервере. Как определить, какой процесс использует пространство подкачки в Unix/Linux?
Вы можете использовать любой из следующих методов (но имейте в виду, что из-за общих страниц, нет никакого надежного способа получить данную информацию):
- Используйте «/proc/meminfo» – Утилита, которая покажет общие сведения об RAM/SWAP. Данная статистика используется с утилитой «free», чтобы сообщить количество свободной и используемой памяти (как физической, так и swap) в системе, а также общей памяти и буферов используемых ядром. Вы также можете использовать free, vmstat и другие инструменты чтобы узнать ту же информацию.
- «/proc/$/smaps», «/proc/$/status» и «/proc/$/stat» — Используя эти утилиты, чтобы найти информацию о памяти, страницах и swap-е используемых каждым процессом( зная PID процесса).
- Используя smem.
Какие процессы заняли SWAP в Unix/Linux
Можно добиться желаемого результата несколькими способами.
Находим идентификатор процесса (PID):
Альтернатива, использовать «pgrep» команду для поиска PID-а:
И так, одна из команд выведет подобный результат:
Чтобы увидеть сколько использует swap служба memcached можно следующим образом:
# cat /proc/79225/status | grep -E "VmSwap"
И так, я показал сколько используется swap-а по указанному процессу ( memcached), но это не совсем удобно т.к имеется и ряд других процессов которые могут или использует swap, по этому — я сейчас покажу как можно красиво использовать данные утилиты для проверки.
Введите следующую команду в терменале, чтобы увидеть использование свопа по каждому процессу:
# for file in /proc/*/status ; do awk '/VmSwap|Name/END< print "">' $file; done
Небольшая оптимизация — используем сортировку и вывод частями:
for file in /proc/*/status ; do awk '/VmSwap|Name/END< print "">' $file; done | sort -k 2 -n -r | less
< date;for f in /proc/3*/status; do awk 'END < if (k["VmSwap:"]) print k["Pid:"],k["Name:"],k["VmSwap:"];>' $f 2>/dev/null; done | sort -n ; >
Нашел небольшой bash скрипт:
# vim /usr/local/src/swap_processes_checker.sh
#!/bin/bash # Get current swap usage for all running processes # Erik Ljungstrom 27/05/2011 SUM=0 OVERALL=0 for DIR in `find /proc/ -maxdepth 1 -type d | egrep "^/proc/4"` ; do PID=`echo $DIR | cut -d / -f 3` PROGNAME=`ps -p $PID -o comm --no-headers` for SWAP in `grep Swap $DIR/smaps 2>/dev/null| awk '< print $2 >'` do let SUM=$SUM+$SWAP done echo "PID=$PID - Swap used: $SUM - ($PROGNAME )" let OVERALL=$OVERALL+$SUM SUM=0 done echo "Overall swap used: $OVERALL"
Запускайте его от суперпользователя для того, чтобы иметь возможность собрать точные цифры. Скрипт будет работать и от любого другого пользователя в системе, но если у него не поулчится получить доступ к процессу которые не принадлежат вашему пользователю, то он не сможет показать данные по процессам. Например, чтобы найти процесс с большим использованием свопа, просто запустите скрипт вот так:
$ sudo bash /usr/local/src/swap_processes_checker.sh | sort -n -k 5
Данные скрипт покажет все процессы которые используют или не используют SWAP, но можно убрать ненужно ( отображать только те процессы, которые имеют обращение к свапу):
$ sudo bash /usr/local/src/swap_processes_checker.sh| egrep -v "Swap used: 0" |sort -n -k 5
Вот уже готовый, упрощенный скрипт:
#!/bin/bash SUM=0 OVERALL=0 for DIR in `find /proc/ -maxdepth 1 -type d -regex "^/proc/1+"` do PID=`echo $DIR | cut -d / -f 3` PROGNAME=`ps -p $PID -o comm --no-headers` for SWAP in `grep VmSwap $DIR/status 2>/dev/null | awk '< print $2 >'` do let SUM=$SUM+$SWAP done if (( $SUM > 0 )); then echo "PID=$PID swapped $SUM KB ($PROGNAME)" fi let OVERALL=$OVERALL+$SUM SUM=0 done echo "Overall swap used: $OVERALL KB"
Хочу показать отличную вариацию данного скрипта ( на мой взгляд — одно из самых лучших):
#!/bin/bash SCRIPT_NAME=`basename $0`; SORT="kb"; #as first parameter, [default: kb] [ "$1" != "" ] && < SORT="$1"; >[ ! -x `which mktemp` ] && < echo "ERROR: mktemp is not available!"; exit; >MKTEMP=`which mktemp`; TMP=`$ -d`; [ ! -d "$" ] && < echo "ERROR: unable to create temp dir!"; exit; >>$/$.pid; >$/$.kb; >$/$.name; SUM=0; OVERALL=0; echo "$" > $/$.overal; for DIR in `find /proc/ -maxdepth 1 -type d -regex "^/proc/1+"`; do PID=`echo $DIR | cut -d / -f 3` PROGNAME=`ps -p $PID -o comm --no-headers` for SWAP in `grep Swap $DIR/smaps 2>/dev/null| awk '< print $2 >'` do let SUM=$SUM+$SWAP done if (( $SUM > 0 )); then echo -n "."; echo -e "$\t$\t$" >> $/$.pid; echo -e "$\t$\t$" >> $/$.kb; echo -e "$\t$\t$" >> $/$.name; fi let OVERALL=$OVERALL+$SUM SUM=0 done echo "$" > $/$.overal; echo; echo "Overall swap used: $ kB"; echo "========================================"; case "$" in name ) echo -e "name\tkB\tpid"; echo "========================================"; cat $/$.name|sort -r; ;; kb ) echo -e "kB\tpid\tname"; echo "========================================"; cat $/$.kb|sort -rh; ;; pid | * ) echo -e "pid\tkB\tname"; echo "========================================"; cat $/$.pid|sort -rh; ;; esac rm -fR "$/";
Вот еще один вариант использования:
#!/bin/bash grep VmSwap /proc/3*/status | awk -F':' -v sort="$1" ' < split($1,pid,"/") # Split first field on / split($3,swp," ") # Split third field on space cmdlinefile = "/proc/"pid[3]"/cmdline" # Build the cmdline filepath getline pname[pid[3]] < cmdlinefile # Get the command line from pid swap[pid[3]] = sprintf("%6i %s",swp[1],swp[2]) # Store the swap used (with unit to avoid rebuilding at print) sum+=swp[1] # Sum the swap >END < OFS="\t" # Change the output separator to tabulation print "Pid","Swap used","Command line" # Print header if(sort) < getline max_pid < "/proc/sys/kernel/pid_max" for(p=1;p<=max_pid;p++) < if(p in pname) print p,swap[p],pname[p] # print the values >> else < for(p in pname) < # Loop over all pids found print p,swap[p],pname[p] # print the values >> print "Total swap used:",sum # print the sum >'
Они все работают и их можно использовать для своих нужд. А можно использовать утилиту smem. О ней можно прочитать тут:
А на этом, у меня все! Статья «Какие процессы заняли SWAP в Unix/Linux» завершена.
Best way to tell what application/process is using swap?
I have 16G RAM, and 8G swap partition. I’m running Unity 17.04. I have a problem where my buff/cache goes to 11M, and my swap used goes to around 3500. Previously I almost never used any swap space, and I’ve never monitored the buff/cache. I believe that it’s an application with a memory leak, but I could be wrong. Simple question. Is there any easy way to determine with application/process is, or has been, using swap?
One other possibility is that vm.swappiness might be set high, which can push things into swap if the OS thinks it won’t need them for a long time, even if there’s plenty of open RAM.
@ChaiT.Rex hum. I wonder. pre 17.04 I had vm.swappiness=10. but after I upgraded to 17.04 I set it back to the default of 60. I wonder if that’s about the time that I noticed this? I may have to set it back and see what happens. Thanks!
@ChaiT.Rex well, I played with vm.swappiness, and finally settled on =10 again, like it was before. My buff/cache usage is still 11-12G after a few days, but I guess that’s normal, as long as the avail Mem stays high. If you make your comment into an answer, I can vote/accept it.
1 Answer 1
You can find that how much does special process uses swap partition by this command :
cat /proc/"PID"/status | grep "^VmSwap"
And you can find PID by this command:
ps -A | grep "Application_name"
But if you want to find which processes are using the swap partition, you can use this script:
#!/bin/bash for i in /proc/*/status ; do vmswap=$(cat $i | grep "^VmSwap") echo "$vmswap" | grep -qv ' 0 kB' if [ $? == 0 ] && [ "$vmswap" != "" ] ; then echo "$i : $vmswap" fi done
Then you can find the application name from its PID that’s returned by the script.
Update: I changed this script to create log file every 10 second (you can change the time) and in that file you can see many processes from the moment you run this script up to now:
#!/bin/bash counter=1 touch ~/swap_process_usage.log while true ; do echo -e "************************************\nSwap's process in count $counter " >> ~/swap_process_usage.log for i in /proc/*/status ; do vmswap=$(cat $i | grep "^VmSwap") echo "$vmswap" | grep -qv ' 0 kB' if [ $? == 0 ] && [ "$vmswap" != "" ] ; then pid=$(echo "$i" | tr -d /proc/ | tr -d status) proc_name=$(ps -p $pid -o comm=) echo "$proc_name : $pid : $vmswap" >> ~/swap_process_usage.log fi done sleep 10s counter=$((counter+1)) done
And you can set this script to run at startup so it creates log every time.
Как узнать, что забивает swap?
Обычно раздел подкачки пустой и заполняется лишь при работе с очень большими графическими файлами. Но уже второй день творится какой-то непорядок. Можно решить проблему выходом и повторным входом в учётную запись, но мне интересно узнать, что именно забивает swap. Как это узнать? Кроме браузеров, NetBeans, аудио, видео и виртуальной машины ничего не запускал. Ничего особенного не делал — все как всегда. Раньше я по две недели не выходил из системы и все было хорошо.
3 ответа 3
Найдено где-то на просторах и немного допилено под свою среду. Возможно, придётся допиливать тоже, главное — понять принцип:
#!/bin/sh for dir in $(find /proc/ -maxdepth 1 -type d |grep -E "2+"); do pid=$(echo $dir |cut -d/ -f3) cmd=$(ps h -o comm -p $pid) swap=$(grep VmSwap $dir/status 2> /dev/null |awk '') if [ ! -z $swap ] && [ $swap -ne 0 ]; then echo "pid: $pid command: $cmd swap: $swap KB" fi done | sort -rnk6 | column -t
Можно запустить top и нажать f — отобразится список параметров, которые он (top) может выводить. Выбери отображение SWAP — и ты увидишь какие процессы сколько данных там держат. А отсортировать по этой колонке можно нажав F.
#!/bin/bash # Get current swap usage for all running processes # Erik Ljungstrom 27/05/2011 SUM=0 OVERALL=0 for DIR in `find /proc/ -maxdepth 1 -type d | egrep "^/proc/7"` ; do PID=`echo $DIR | cut -d / -f 3` PROGNAME=`ps -p $PID -o comm --no-headers` for SWAP in `grep Swap $DIR/smaps 2>/dev/null| awk '< print $2 >'` do let SUM=$SUM+$SWAP done echo "PID=$PID - Swap used: $SUM - ($PROGNAME )" let OVERALL=$OVERALL+$SUM SUM=0 done echo "Overall swap used: $OVERALL"
Хочу ответить откуда взялась проблема с swap-space. Это мог бы быть этот баг http://osdir.com/ml/ubuntu-bugs/2016-03/msg00360.html , но у меня версия 14.04, так что это не мой случай.
xuser@mh:~$ df -h Файл.система Размер Использовано Дост Использовано% Cмонтировано в udev 3,9G 4,0K 3,9G 1% /dev tmpfs 799M 1,3M 798M 1% /run /dev/sda2 54G 12G 39G 23% / none 4,0K 0 4,0K 0% /sys/fs/cgroup tmpfs 1,0G 183M 842M 18% /tmp none 5,0M 0 5,0M 0% /run/lock none 3,9G 1,4M 3,9G 1% /run/shm none 100M 20K 100M 1% /run/user tmpfs 1,5G 291M 1,2G 20% /home/xuser/.cache tmpfs 512M 199M 314M 39% /home/xuser/.mozilla tmpfs 5,0G 0 5,0G 0% /home/xuser/torTmp /dev/sdb1 230G 108G 111G 50% /media/xuser/9bd1fae0-bcb9-4677-9f1a-28ac7079dccc xuser@mh:~$
Я запускал виртуальную машину и забыл очистить папку
а она у меня предназначена для торрентов и образа виртуальной машины.
писало ошибку о том что не может распределить память.
Я потом и догадался что нужно глянуть что же у меня в системе с памятью происходит. Конец истории :).