在Linux下,如何发现哪个进程使用交换空间更多?
当前回答
与@lolotux相同的答案,但有排序输出:
printf 'Computing swap usage...\n';
swap_usages="$(
SUM=0
OVERALL=0
for DIR in `find /proc/ -maxdepth 1 -type d -regex "^/proc/[0-9]+"`
do
PID="$(printf '%s' "$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
printf "$SUM KB ($PROGNAME) swapped PID=$PID\\n"
fi
let OVERALL=$OVERALL+$SUM
SUM=0
break
done
printf '9999999999 Overall swap used: %s KB\n' "$OVERALL"
)"
printf '%s' "$swap_usages" | sort -nk1
示例输出:
Computing swap usage...
2064 KB (systemd) swapped PID=1
59620 KB (xfdesktop) swapped PID=21405
64484 KB (nemo) swapped PID=763627
66740 KB (teamviewerd) swapped PID=1618
68244 KB (flameshot) swapped PID=84209
763136 KB (plugin_host) swapped PID=1881345
1412480 KB (java) swapped PID=43402
3864548 KB (sublime_text) swapped PID=1881327
9999999999 Overall swap used: 2064 KB
其他回答
给出使用交换的进程的总数和百分比
smem -t -p
来源:https://www.cyberciti.biz/faq/linux-which-process-is-using-swap/
运行top,然后按OpEnter。现在进程应该根据它们的交换使用情况进行排序。
这是一个更新,因为我原来的答案没有提供一个确切的答案,在评论中指出的问题。从htop常见问题:
It is not possible to get the exact size of used swap space of a process. Top fakes this information by making SWAP = VIRT - RES, but that is not a good metric, because other stuff such as video memory counts on VIRT as well (for example: top says my X process is using 81M of swap, but it also reports my system as a whole is using only 2M of swap. Therefore, I will not add a similar Swap column to htop because I don't know a reliable way to get this information (actually, I don't think it's possible to get an exact number, because of shared pages).
这是脚本的另一个变体,但意味着提供更可读的输出(你需要以根用户身份运行这个脚本才能得到准确的结果):
#!/bin/bash
# find-out-what-is-using-your-swap.sh
# -- Get current swap usage for all running processes
# --
# -- rev.0.3, 2012-09-03, Jan Smid - alignment and intendation, sorting
# -- rev.0.2, 2012-08-09, Mikko Rantalainen - pipe the output to "sort -nk3" to get sorted output
# -- rev.0.1, 2011-05-27, Erik Ljungstrom - initial version
SCRIPT_NAME=`basename $0`;
SORT="kb"; # {pid|kB|name} as first parameter, [default: kb]
[ "$1" != "" ] && { SORT="$1"; }
[ ! -x `which mktemp` ] && { echo "ERROR: mktemp is not available!"; exit; }
MKTEMP=`which mktemp`;
TMP=`${MKTEMP} -d`;
[ ! -d "${TMP}" ] && { echo "ERROR: unable to create temp dir!"; exit; }
>${TMP}/${SCRIPT_NAME}.pid;
>${TMP}/${SCRIPT_NAME}.kb;
>${TMP}/${SCRIPT_NAME}.name;
SUM=0;
OVERALL=0;
echo "${OVERALL}" > ${TMP}/${SCRIPT_NAME}.overal;
for DIR in `find /proc/ -maxdepth 1 -type d -regex "^/proc/[0-9]+"`;
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 "${PID}\t${SUM}\t${PROGNAME}" >> ${TMP}/${SCRIPT_NAME}.pid;
echo -e "${SUM}\t${PID}\t${PROGNAME}" >> ${TMP}/${SCRIPT_NAME}.kb;
echo -e "${PROGNAME}\t${SUM}\t${PID}" >> ${TMP}/${SCRIPT_NAME}.name;
fi
let OVERALL=$OVERALL+$SUM
SUM=0
done
echo "${OVERALL}" > ${TMP}/${SCRIPT_NAME}.overal;
echo;
echo "Overall swap used: ${OVERALL} kB";
echo "========================================";
case "${SORT}" in
name )
echo -e "name\tkB\tpid";
echo "========================================";
cat ${TMP}/${SCRIPT_NAME}.name|sort -r;
;;
kb )
echo -e "kB\tpid\tname";
echo "========================================";
cat ${TMP}/${SCRIPT_NAME}.kb|sort -rh;
;;
pid | * )
echo -e "pid\tkB\tname";
echo "========================================";
cat ${TMP}/${SCRIPT_NAME}.pid|sort -rh;
;;
esac
rm -fR "${TMP}/";
自2015年内核补丁添加SwapPss (https://lore.kernel.org/patchwork/patch/570506/)以来,人们终于可以得到成比例的交换计数,这意味着如果一个进程交换了很多,然后它分叉,两个分叉的进程将分别报告交换50%。如果其中一个发生分叉,每个进程被计算为交换页面的33%,所以如果你把所有的交换使用量计算在一起,你得到的是真实的交换使用量,而不是数值乘以进程数。
简而言之:
(cd /proc; for pid in [0-9]*; do printf "%5s %6s %s\n" "$pid" "$(awk 'BEGIN{sum=0} /SwapPss:/{sum+=$2} END{print sum}' $pid/smaps)" "$(cat $pid/comm)"; done | sort -k2n,2 -k1n,1)
第一列是pid,第二列是KiB中的交换使用情况,其余一行是正在执行的命令。相同的交换计数按pid排序。
上面可能会发出这样的行
awk: cmd. line:1: fatal: cannot open file `15407/smaps' for reading (No such file or directory)
这仅仅意味着pid为15407的进程在/proc/的列表中看到它和读取进程smaps文件之间结束。如果这对您来说很重要,只需在末尾添加2>/dev/null即可。请注意,您可能还会丢失任何其他可能的诊断。
在现实世界的示例案例中,这改变了其他报告在一台服务器上运行的每个apache子服务器使用约40 MB交换空间的工具,而每个子服务器实际使用7-3630 KB交换空间。
您可以使用Procpath(作者在这里),以简化从/proc/$PID/status解析vmswwap。
$ procpath record -f stat,cmdline,status -r 1 -d db.sqlite
$ sqlite3 -column db.sqlite \
'SELECT status_name, status_vmswap FROM record ORDER BY status_vmswap DESC LIMIT 5'
Web Content 192136
okular 186872
thunderbird 183692
Web Content 143404
MainThread 86300
您还可以像这样绘制感兴趣的进程的vmswwap。在这里,我正在记录Firefox进程树,同时打开几十个选项卡,并启动一个占用大量内存的应用程序,试图导致它进行交换(这对Firefox来说并不令人信服,但您的情况可能不同)。
$ procpath record -f stat,cmdline,status -i 1 -d db2.sqlite \
'$..children[?(@.stat.pid == 6029)]'
# interrupt by Ctrl+C
$ procpath plot -d db2.sqlite -q cpu --custom-value-expr status_vmswap \
--title "CPU usage, % vs Swap, kB"
推荐文章
- 在Bash中检查变量是否存在于列表中
- 查看PS命令的全部输出
- Linux命令将域名转换为IP
- 如何从命令行在windows中找到mysql数据目录
- 有效地测试Linux上的端口是否打开?
- 如何从另一个文件A中删除文件B中出现的行?
- 对以制表符分隔的文件进行排序
- 如何在Java中监控计算机的CPU、内存和磁盘使用情况?
- 在内存的哪里我的变量存储在C?
- 使用sudo时未找到命令
- 当有命令行参数时,如何使用GDB分析程序的核心转储文件?
- 如何强制从另一个SSH会话分离屏幕?
- 如何将文件指针(file * fp)转换为文件描述符(int fd)?
- Linux Bash中双&和分号有什么区别?
- 多维数组如何在内存中格式化?