linux打印jvm内存堆栈_Java进程在Linux生产环境下的问题分析和解决大全

有了监控,当某个java服务不正常的时候就会报警,这样就实现了有问题提前感知。

1.编写脚本

文件名为:checkJavaCpu.sh

内容:

#!/bin/sh

ShellAbsPath=$(cd "$(dirname "$0")"; pwd)

function checkCpu(){

ID=$1

pid=`ps aux|grep "dubbo${ID}"|grep -v "grep"|awk '{print $2}'|head -n 1`

nowCpu=`top -b -n 1 | grep ${pid} | awk '{print int($9)}'`

if [ ${nowCpu} -gt 200 ];then

TimeLike=`date "+%d/%b/%Y:%H:%M"`

#sendMail.sh

fi;

}

IDArr=('1' '2');

length=${#IDArr[@]}

for ((i=0; i

do=${I

IDDArr[$i]}

checkCpu ${ID}

done

2.添加定时任务,每分钟检测一次* */1 * * * /home/gameboys/checkJavaCpu.sh

通常linux上面可以使用下面命令初步查看java进程情况,windows下直接使用jdk里面的工具直接可视界面查看

1.查看所有java进程jps

2.查看某java进程的信息jinfo pid

3.java堆栈跟踪工具jstack pid

4.查看gc情况,下面命令第四位标识打印间隔,第5位为打印多少次jstat -gcutil pid 1000 5

5.查看java进程的内存映像工具jmap -heap pid

6.查看当前java进程堆对象统计信息jmap -histo pid

7.出问题再使用的命令,平时别用,dump出内存情况jmap -dump:live,format=b,file=tmp.hprof pid

8.jdk自带的反解析工具javap -verbose TestClass

经验中有两种情况会出现cpu飙高,分别是死循环或者频繁GC

1.通过top命令查看pidtop

2.找到子进程号top -H -p pid

3.查看16进制编号printf %x subPid

4.查看堆栈线程状态jstack pid >tmp

5.通过查找tmp里面的16进制id可以找到对应的线程是哪个,进而解决

前提是内存,意思down到本地使用window工具排查不太可能,因为dump出来的文件基本上2G以上,一般出现内存泄漏多半是ConcurrentHashMap越来越大导致,笔者遇到过不下于5次,所以很多情况下不确定能清理的数据使用LRUMap,处理这类问题先使用jstat -histo 查看占用较大的对象,然后对应代码分析,20%的几率是可以解决,如果没法定位,那么使用终极武器:

1.下载linux的mat工具,下载地址:

# 运行uname -m看一下linux是x86_64还是x86的帮助你选择下载那个版本。uname -mwget http://mirrors.neusoft.edu.cn/eclipse/mat/1.9.0/rcp/MemoryAnalyzer-1.9.0.20190605-linux.gtk.x86_64.zip

2.解压unzip MemoryAnalyzer-1.9.0.20190605-linux.gtk.x86_64.zip

3.配置mat

修改MAT的内存大小, 注意这个大小要根据你dump文件大小来的,如果dump文件是5GB那么 这里最好配>5GB否则会报MAT内存不足的异常

## 修改MemoryAnalyzer.ini的-Xmx6024m

4.dump出java的内存信息jmap -dump:live,format=b,file=tmp.hprof pid

5.使用脚本在linux上面分析(注:服务器空闲内存必须大于配置内存,如果内存不够,则先压缩之后scp到一台空闲服务器处理)./ParseHeapDump.sh /tmp.hprof org.eclipse.mat.api:suspects org.eclipse.mat.api:overview org.eclipse.mat.api:top_components

6.下载分析好的文件并解压,通过浏览器打开分析,

三个文件分别为:a_Leak_Suspects.zipa_System_Overview.zip a_Top_Components.zip

7.压缩和scp命令zip a.zip a

复制文件scp -P 6666 local_file remote_username@remote_ip:remote_folder

复制文件夹scp -P 6666 -r local_folder remote_username@remote_ip:remote_folder

五、附带送一个Linux的dump脚本

拷贝下面脚本到服务器,命名为dump.sh,检查java环境变量配置,然后执行./dump.sh pid

#!/bin/bash

cd `dirname $0`

BIN_DIR=`pwd`

PID=$1

DATE=`date +%Y%m%d`

DATE_DIR=${BIN_DIR}/dump/$DATE

#创建目录,如果没有的时候

mkdir -p ${BIN_DIR}/dump/$DATE

jstack $PID > $DATE_DIR/jstack-$PID.dump 2>&1

echo -e ".\c"

jinfo $PID > $DATE_DIR/jinfo-$PID.dump 2>&1

echo -e ".\c"

jstat -gcutil $PID > $DATE_DIR/jstat-gcutil-$PID.dump 2>&1

echo -e ".\c"

jstat -gccapacity $PID > $DATE_DIR/jstat-gccapacity-$PID.dump 2>&1

echo -e ".\c"

jmap $PID > $DATE_DIR/jmap-$PID.dump 2>&1

echo -e ".\c"

jmap -heap $PID > $DATE_DIR/jmap-heap-$PID.dump 2>&1

echo -e ".\c"

jmap -histo $PID > $DATE_DIR/jmap-histo-$PID.dump 2>&1

echo -e ".\c"

if [ -r /usr/sbin/lsof ]; then

/usr/sbin/lsof -p $PID > $DATE_DIR/lsof-$PID.dump

echo -e ".\c"

fi

if [ -r /bin/netstat ]; then

/bin/netstat -an > $DATE_DIR/netstat.dump 2>&1

echo -e ".\c"

fi

if [ -r /usr/bin/iostat ]; then

/usr/bin/iostat > $DATE_DIR/iostat.dump 2>&1

echo -e ".\c"

fi

if [ -r /usr/bin/mpstat ]; then

/usr/bin/mpstat > $DATE_DIR/mpstat.dump 2>&1

echo -e ".\c"

fi

if [ -r /usr/bin/vmstat ]; then

/usr/bin/vmstat > $DATE_DIR/vmstat.dump 2>&1

echo -e ".\c"

fi

if [ -r /usr/bin/free ]; then

/usr/bin/free -t > $DATE_DIR/free.dump 2>&1

echo -e ".\c"

fi

if [ -r /usr/bin/sar ]; then

/usr/bin/sar > $DATE_DIR/sar.dump 2>&1

echo -e ".\c"

fi

if [ -r /usr/bin/uptime ]; then

/usr/bin/uptime > $DATE_DIR/uptime.dump 2>&1

echo -e ".\c"

fi

echo "OK!"

echo "DUMP: $DATE_DIR"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值