Linux Bash-脚本在长时间运行时,CPU使用率从3%提高到100%
我写了一个脚本,收集了一些系统统计数据。这与压力测试一起运行,以便可以收集有关系统的SAT。收集的统计数据包括CPU使用率(使用sar)、内存使用率(使用空闲)、中断等。通过将收集到的每个数据点放在后台,将其生成到单独的进程中。要将此数据移动到csv文件,以便可以在电子表格中打开,需要进行一些后期处理。后处理也发生在派生的进程中。脚本在采集的样本之间有睡眠间隔。但是,后台进程在此时间间隔内仍在运行 我观察到,当这个脚本运行很长时间时,仅这个脚本的CPU使用率就从3%左右逐渐增加到几乎100%。这是一个令人不安的场景,因为不能允许分析脚本占用如此多的CPU时间。(我使用“top”记录每个进程的CPU使用情况) 另一个有趣的观察结果是,在压力测试中运行的重载进程占用的CPU时间比该脚本少(在其使用率超过90%之后) 如何解决这个问题?我有什么遗漏吗?请指教 在下面添加一些代码位。下面是主循环Linux Bash-脚本在长时间运行时,CPU使用率从3%提高到100%,linux,bash,cpu,cpu-usage,Linux,Bash,Cpu,Cpu Usage,我写了一个脚本,收集了一些系统统计数据。这与压力测试一起运行,以便可以收集有关系统的SAT。收集的统计数据包括CPU使用率(使用sar)、内存使用率(使用空闲)、中断等。通过将收集到的每个数据点放在后台,将其生成到单独的进程中。要将此数据移动到csv文件,以便可以在电子表格中打开,需要进行一些后期处理。后处理也发生在派生的进程中。脚本在采集的样本之间有睡眠间隔。但是,后台进程在此时间间隔内仍在运行 我观察到,当这个脚本运行很长时间时,仅这个脚本的CPU使用率就从3%左右逐渐增加到几乎100%。这
while true
do
if [ $exitstatus = 0 ]
then
exitScript
fi
let itr++
echo -e "\n Interation: $itr\n"
if [ "$3" = "ALL" ]
then
export CALC_INTERRUPTS=1
printTitle "sar"
processCommand "sar" &
#printTitle "free"
processCommand "free" &
printTitle "interrupts"
processCommand "interrupts" &
printTitle "underflows"
processCommand "underflows" &
#printTitle "clocktree"
processCommand "clocktree" &
else
if [ $itr -eq 1 ]
then
shift 2
fi
for com in "$@"
do
printTitle "$com"
processCommand "$com" &
done
fi
#printTimestamp > $TEMP_LOC/sys.log
cat /var/log/syslog > $TEMP_LOC/sys.log
if [ $exitstatus = 0 ]
then
exitScript
fi
sleep $interval
#Wait for background jobs from the last iteration to finish
for job in `jobs -p`
do
wait $job
done
cat $TEMP_LOC/*.temp >> $TEMP_LOC/monitor.log
rm -f $TEMP_LOC/*.temp
if [ $(($itr % 180)) -eq 0 ]
then
takeDump
fi
done
fi
以下是CPU使用情况的记录和后处理(使用sar)——
processCommand()
{
案件“$1”
(合成孔径雷达)
打印时间戳>>$TEMP\u LOC/$1.TEMP
#echo-n“记录CPU统计信息……”
exe=“sar-P ALL 1”
$exe>$TEMP\u LOC/TEMP\u sar
echo-e“\n\n使用超过1%CPU时间的进程:”>>$TEMP\u LOC/$1.TEMP
顶部-b-n 1>$TEMP\U LOC/TEMP\U top
#删除除当前CPU统计信息之外的所有行
sed-i“5,8!d”$TEMP_LOC/TEMP_sar
#用逗号替换所有空格
sed-i的/[:space:][]\+/,/g'$TEMP\u LOC/TEMP\u sar
Cpu=0
而[-s$TEMP_LOC/TEMP_sar]
做
#如果文件不存在,则添加标题
如果[!-f$TEMP\U LOC/Cpu$Cpu.csv]
然后
printf“时间,$Cpu.us,$Cpu.ni,$Cpu.sy,$Cpu.wa,$Cpu.st,$Cpu.id,$Cpu.total\n”>>$TEMP\u LOC/Cpu$Cpu.csv
fi
#删除CPU号
统计数据=`sed-n'1p'$TEMP_LOC/TEMP_sar | cut-d','--补码-f2`
空闲=`echo$stats | cut-d','-f7`
#将CPU总使用率计算为100空闲
总使用率=$(bc$TEMP\U LOC/Cpu$Cpu.csv
sed-i'1d'$TEMP_LOC/TEMP_sar
让Cpu++
完成
;;
代码的其他部分也起着类似的作用。定期拍摄该参数的快照并对其进行一些后处理。尝试在/proc“files”上使用单个awk,而不是使用多种工具,如free、sar、ps-C
使用一个脚本而不在shell上保留变量,可以避免一些内存/cpu泄漏,比如在每个循环中忘记清理的shell变量,然后在上面执行grep操作。可以发布脚本内容吗?是否将所有数据保留在内存中?是否覆盖CSV文件或只是添加新数据?面积逐渐增加ds?还要注意,总CPU%是CPU%/CPU核心数。@choroba,是的,所有数据都在内存中。我挂载了RAMFS并保留了所有的临时数据。@krampstudio,脚本非常大(大约500行左右)。你想让我粘贴整个内容吗?内存泄漏会导致CPU使用率峰值吗?不会。但是如果此shell脚本的内存正在增长,可能会显示一些一直在使用的变量,而不进行清理,并操纵巨大的变量,CPU使用率峰值是否为ps。对不起,可怜的英国汉克斯·布伦诺桑。将尝试相同的:)
processCommand()
{
case "$1" in
sar)
printTimestamp>> $TEMP_LOC/$1.temp
#echo -n " Logging CPU stats............ "
exe="sar -P ALL 1 1"
$exe > $TEMP_LOC/temp_sar
echo -e "\n\n Processes using more than 1% of CPU time: " >> $TEMP_LOC/$1.temp
top -b -n 1 > $TEMP_LOC/temp_top
#delete all lines except current CPU statistics
sed -i "5,8! d" $TEMP_LOC/temp_sar
#replace all spaces with commas
sed -i 's/[[:space:]]\+/,/g' $TEMP_LOC/temp_sar
Cpu=0
while [ -s $TEMP_LOC/temp_sar ]
do
#if file does not exist then add the header
if [ ! -f $TEMP_LOC/Cpu$Cpu.csv ]
then
printf "time,$Cpu.us,$Cpu.ni,$Cpu.sy,$Cpu.wa,$Cpu.st,$Cpu.id,$Cpu.total\n" >> $TEMP_LOC/Cpu$Cpu.csv
fi
#remove CPU number
stats=`sed -n '1p' $TEMP_LOC/temp_sar | cut -d ',' --complement -f 2`
idle=`echo $stats | cut -d ',' -f 7`
#calculate totale CPU usage as 100-idle
total_usage=$(bc <<< "100.00-$idle")
echo "$stats,$total_usage" >> $TEMP_LOC/Cpu$Cpu.csv
sed -i '1d' $TEMP_LOC/temp_sar
let Cpu++
done
;;
time awk ' /MemTotal/ {print $2}; /SwapCached/ {print $2}; /processor/ {print $NF}' /proc/meminfo /proc/cpuinfo
1933536
17840
0
1
real 0m0.002s
user 0m0.000s
sys 0m0.000s