在Linux下,如何发现哪个进程使用交换空间更多?
当前回答
这是我的一句话:
cat /proc/*/status | grep -E 'VmSwap:|Name:' | grep VmSwap -B1 | cut -d':' -f2 | grep -v '\-\-' | grep -o -E '[a-zA-Z0-9]+.*$' | cut -d' ' -f1 | xargs -n2 echo | sort -k2 -n
这一行的步骤是:
Get all the data in /proc/process/status for all processes Select the fields VmSwap and Name for each Remove the processes that don't have the VmSwap field Remove the names of the fields (VmSwap: and Name:) Remove lines with -- that were added by the previous step Remove the spaces at the start of the lines Remove the second part of each process name and " kB" after the swap usage number Take name and number (process name and swap usage) and put them in one line, one after the other Sort the lines by the swap usage
其他回答
另一种在shell中避免循环的脚本变体:
#!/bin/bash
grep VmSwap /proc/[0-9]*/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
}'
标准用法是script.sh以随机顺序获取每个程序的使用情况(直到awk如何存储其哈希值)或script.sh 1以pid对输出进行排序。
我希望我已经对代码进行了足够的注释,以说明它的功能。
我认为,您可以通过运行top并查找使用大量内存的活动进程来得到一个很好的猜测。通过编程实现这一点比较困难——只要看看关于Linux OOM杀手启发式的无休止的争论就知道了。
交换是一种活动使用的内存比安装的内存多的功能,因此通常很难将其归咎于单个进程。如果这是一个持续的问题,最好的解决方案是安装更多的内存,或进行其他系统更改。
我不知道如何确切地找到哪个进程正在使用交换空间的直接答案,但是,这个链接可能会有帮助。另一个好例子在这里
另外,使用像htop这样的好工具来查看哪些进程使用了大量内存,以及总体上使用了多少交换空间。
这是我的一句话:
cat /proc/*/status | grep -E 'VmSwap:|Name:' | grep VmSwap -B1 | cut -d':' -f2 | grep -v '\-\-' | grep -o -E '[a-zA-Z0-9]+.*$' | cut -d' ' -f1 | xargs -n2 echo | sort -k2 -n
这一行的步骤是:
Get all the data in /proc/process/status for all processes Select the fields VmSwap and Name for each Remove the processes that don't have the VmSwap field Remove the names of the fields (VmSwap: and Name:) Remove lines with -- that were added by the previous step Remove the spaces at the start of the lines Remove the second part of each process name and " kB" after the swap usage number Take name and number (process name and swap usage) and put them in one line, one after the other Sort the lines by the swap usage
这是脚本的另一个变体,但意味着提供更可读的输出(你需要以根用户身份运行这个脚本才能得到准确的结果):
#!/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}/";
推荐文章
- 有效地测试Linux上的端口是否打开?
- 如何从另一个文件A中删除文件B中出现的行?
- 对以制表符分隔的文件进行排序
- 如何在Java中监控计算机的CPU、内存和磁盘使用情况?
- 在内存的哪里我的变量存储在C?
- 使用sudo时未找到命令
- 当有命令行参数时,如何使用GDB分析程序的核心转储文件?
- 如何强制从另一个SSH会话分离屏幕?
- 如何将文件指针(file * fp)转换为文件描述符(int fd)?
- Linux Bash中双&和分号有什么区别?
- 多维数组如何在内存中格式化?
- 在SSH会话中查找客户端的IP地址
- C++ Linux的想法?
- 如何为Fedora安装g++ ?
- Linux删除大小为0的文件