Arthas(阿尔萨斯)
简介 | arthas, Alibaba 开源的 Java 诊断工具,参照文档安装使用很简单,在线下载或者离线下载后解压运行,启动arthas-boot.jar,会自动扫描jps进程,根据序号选择后进入arthas界面:
tar -zxvf arthas-offline.tar.gz
cd arthas
yum install -y java
yum install -y java-1.8.0-openjdk-devel
java -jar arthas-boot.jar
java -jar arthas-boot.jar
* [1]: 105241
[2]: 454265 test.jar
常用的是dashboard,thread命令,dashboard命令能扫面当前java进程的全局信息,包括堆栈和线程信息,
dashboard的第二个显示框Memory动态地详细展示了当前jar包的堆内存heap,非堆内存nonheap,代码缓存区code_cache,元数据空间metaspace等信息,其中heap堆内存的total总量是XMS设置的大小,除非不够用还会跟系统申请,但区间就是[Xms,Xmx],堆内存的总数+非堆内存总数+代码缓存区+元数据空间+压缩的class空间就可以理解成是占用的系统的t最小内存了,但系统内存占用肯定不止这么少;
其中第一列展示的是总堆内存的大小和占用比例,其下又分为3个区域:EC,OC,S1C,分别是新生代总空间,老年代总空间,S1总空间,EU,OU,S1U,新生代使用空间,老年代使用空间,S1使用空间,三者之和可以理解成已经使用的总的从系统那里申请的内存,arthas都会展示这个usage,
Memory used total max usage GC
head 248m 512m 512m 50%
上面这个可以看出最大的head=total值,说明Xms和Xmx设置的是一样的,也就是jar包启动后就像内存申请了这么大的空间,如果两者不等,这个toal可能是介于Xms和Xmx之间的某个值的;
thread命令则是更详细的线程信息,thread命令罗列所有线程的基本信息,thread -tid,tid指的是线程id可以更详细看线程目前状态;
问题描述
生产环境中的单体应用,其运行内存达到5G,远大于jar启动时候指定的最大堆内存(512M)+非堆内存+其他,使用命令行:
# 单位是M
ps -aux |grep xxxx.jar |grep -v grep| awk '{total+=$6}; END {print total/1000}'
发现其占用内存的数值还在持续增长中,使用jstat命令查看其堆栈信息发现并没有频繁FGC,而且新生代和老年带分布正常,所以结论就是堆外内存溢出:
# 查看进程号
jps
# 查看 43063进程的gc情况,2s一次,打印5次
jstat -gc 43063 2000 5
# EC,OC,S1C,分别是新生代总空间,老年代总空间,S1总空间
# EU,OU,S1U,新生代使用空间,老年代使用空间,S1使用空间
# YGC FGC分别是young gc和full gc的次数,fgc越小说明越稳定
# YGCT FGCT 分别是young gc和 full gc花费的时间
# MC MU是 metaspace空间,如果长期占用说明这个jar包经常使用反射和代理经常访问class的元数据信息
# jstat信息都可以通过arthas查看
该情况下可以查看进程启动的线程数,使用jstack查看该进程的线程数达到了10万+,且使用的线程方式是线程池的报错,那么问题绝大部分可能就是线程的启动占用了系统内存,造成内存泄漏;
# 查看43063进程启动的线程数
jstack -l 43063
使用arthas的thread命令查看线程池报错信息发现线程池的调度方式是:LinkedBlockingQueue,找到代码中的调度方式发现,该线程池在定时任务中,每过3分钟启动1个该线程池,活跃线程数是10;
解决办法
将该线程池改为全局的对象,被bean持有,定时任务每次拿到同1个线程池,而不是每次创建新的线程池,修改后问题修复;
JAR包相关jvm建议
1、Xms和Xmx设置一样大,让jar包在启动就能申请到最大的内存空间,减少jar包的oom概率,也防止后续不能申请到最大的内存,否则jar包会先申请Xms的内存空间,根据需要再申请;
2、垃圾回收器指定为G1GC,命令: -XX:+UseG1GC
3、使用jdk自带工具进行jar的jvm分析:
jstat(jar stattistics monitoring tool),java统计信息监视恐惧,可以动态查看jvm的堆栈信息状态:jstat -gc pid 2000 5;
jstack(java stack trace tool),java堆栈分析工具,用于生产java应用程序的线程信息,jstack -l pid >test.txt,arthas的thread命令同样可以查看线程信息;文章来源:https://www.toymoban.com/news/detail-836719.html
jhat(java heap analysis tool),java堆分析工具,使用arthas的headdump 可以导出,然后jhat查看,在web的7000端口可视化展示,能方便地找到异常的大对象;文章来源地址https://www.toymoban.com/news/detail-836719.html
到了这里,关于记1次生产环境java进程内存泄漏问题定位(使用Arthas)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!