目前有的那些jvm工具,界面都太难看了,严重影响我的调bug心情
所以我打算直接用jmap来看内存中都有什么东西
但是为什么不直接看gc日志中的Full GC频率呢
因为这个东西跟jvm内存分配和内存大小有关系,而我关心的是内存积存趋势
比如说,举个极端的例子,jvm内存很小,那么肯定每时每刻都在Full GC
但是你的代码真的这么差吗,不一定
但是如果条件很好,jvm内存设定的很大,那么几个月内都不会很频繁的Full GC
但是你的代码真的这么好吗,也不一定
所以归根结底要看内存中的对象是不是一直在累积增长
那么jmap就是个不错的东西
我们知道jmap打印的东西,jmap -histo pid是这个样的:
又臭又长
而且下面的都是内存中只有几个的,没有价值
所以我打算只取前9行,jmap -histo pid | head -12
但是总不能手动输出这个东西,所以我打算用crontab来定时打印它
#!/bin/bash
step=5 #间隔的秒数,不能大于60
echo "get in loop"
for (( i = 0; i < 55; i=(i+step) )); do
echo "in loop"
oldifs="$IFS"
IFS=$'\n'
for lines in `jmap -histo 2866 | head -12`; do
echo "$lines"
done
IFS="$oldifs"
sleep $step
done
但是就是不输出!!!!!
为什么!!!!
后来我想起来了,会不会是这个crontab运行sh时,是跟当前的java环境不相关的,于是我尝试加了下面这段
export JAVA_HOME=/opt/jdk1.8.0_181
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
输出了。。。。
但是还没完,这个输出是不规范的,没有办法用excel查看,所以我要再写个脚本,来将输出的东西,前9行累加,生成新的文件
#!/bin/bash
arr=(1 2 3 4 5 6 7 8 9)
tempSum=0
cat jmap.jmap | while read line
do
echo "${line}"
for element in ${arr[@]}
do
flag=${element}:
result=$(echo $line | grep "${flag}")
if [[ "$result" != "" ]]
then
echo "catch:${flag}"
tempNum=`echo "${line}" | awk '{print $3}'`
let tempSum=$tempSum+$tempNum
if [[ "$flag" == "9:" ]]
then
echo "echo sum:${tempSum}"
echo "${tempSum}" >> result.jmap
let tempSum=0
fi
fi
done
done
这个脚本就是将每一次输出的9行都累加,然后echo>>到新的文件
这样一来,生成的新的文件就能通过excel打开了
然后就可以这么看
好像并没有出现一直上升,不下降的趋势
由此可见代码应该没有出现内存泄漏的情况,或者某些资源不释放导致永久代对象过多的情况