相信大家在性能测试过程中或者生产过程中,会发现应用程序存在这样或者那样的性能问题,比如内存泄漏、CPU使用率过高、服务吞吐量不符合预期、接口响应忽然变慢等等,那么如何分析出程序到底哪里出了问题呢,今天我们就借助JDK自带的jvisualvm.exe工具,一探JVM内部的秘密。
1、TOMCAT项目的JMX配置
1.1、JMX配置项理解
-Djava.rmi.server.hostname=xx.xx.xx.xx -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.rmi.port=XXX -Dcom.sun.management.jmxremote.port=XXX -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.pwd.file=/home/export/servers/jdk1.8.0_91/jre/lib/management/jmxremote.password
hostname表示远程服务器的IP地址。
rmi.port表示jmx使用的端口。
jmxremote.port表示用于监听远程应用连接的端口,指定以上两个端口,要保证他们没有被机器防火墙限制。
pwd.file表示远程连接工具的访问用户名和密码的配置文件,jmxremote.password文件使用JDK文件目录中jre/lib/management文件夹中的密码文件模板(jmxremote.password.template)拷贝一份(cp jmxremote.password.template jmxremote.password),命名为jmxremote.password 放开最后两行,表示两个不同权限的用户,紧跟着是连接密码,可以自定义也可以不改,修改保存之后,给jmxremote.password文件设置访问权限(chmod 400 jmxremote.password)。
其余的配置项默认就好。
1.2、将JMX配置项加入到tomcat的启动文件中
在tomcat安装目录的bin目录下的catalina.sh文件首行,定义一个变量JAVA_OPTS,将1.1的配置信息赋值给JAVA_OPTS变量。
JAVA_OPTS="-Djava.rmi.server.hostname=xx.xx.xx.xx -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.rmi.port=XXX -Dcom.sun.management.jmxremote.port=XXX -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.pwd.file=/home/export/servers/jdk1.8.0_91/jre/lib/management/jmxremote.password"
IP、端口、密码文件地址记得修改哦。
1.3、重启tomcat并测试端口是否在监听
tomcat的bin目录下先执行shutdown.sh再执行startup.sh文件。
启动完成后,使用命令,ps -ef | grep tomcat,查看tomcat的进程号,然后使用命令,netstat -anp | grep 进程号,查看你定义的两个端口是否处于监听状态。
发现定义的端口有处于监听状态,那就大功告成,没有发现相应的监听端口,就要查看是否被防火墙拦截,端口不能使用。
2、SpringBoot项目配置JMX
2.1、将JMX配置加入到Boot项目的启动命令中
可以将配置信息加入到JAVA_OPTS变量中,但是要注意JAVA_OPTS有可能在脚本中被定义为了环境变量,而linux中的环境变量是区分用户权限的,所以用不好就达不到预期的效果,最便捷的方式就是自定义一个变量JAVA_JMX,将jmx的配置信息赋给它,最后再将JAVA_JMX变量加入到启动行中,比如${JAVA_HOME}/bin/java $JAVA_MEM_OPTS $JAVA_OPTS $JAVA_JMX -classpath $CONF_DIR:$LIB_JARS com.xx.xxx.xxx > /dev/null 2>&1 &
保存退出,然后重启程序就好啦,可以使用1.3的命令看看指定的端口有没有在监听状态。
3、JAVA Visualvm使用
3.1、JAVA Visualvm工具安装路径
其安装路径在JDK安装目录下的bin文件夹下的jvisualvm.exe工具,双击即可打开,其为JDK的自带工具,打开之后长这样
3.2、JAVA Visualvm工具介绍
3.2.1、本地监控区
主要监控本机的JAVA进程,有哪些监控指标呢?
概述:
主要展示进程的描述信息。
监视:
进程占用CPU的情况、进程占用JVM堆区的使用情况、类数目、线程概览情况。
线程:
稍微详细的线程情况,主要表示,不同线程的运行状态和繁忙程度。
可以使用右上角的线程dump按钮,将进程中此时的线程状态和堆栈信息记录下来,方便后续分析。
**抽样器: **
CPU样例:
在这个分析中, 可以找到进程中所有的热点方法本身消耗的时间和CPU的耗时,还包含此方法因为调用其他方法而使用的总的CPU和耗时情况,可以使用排序功能,找出最耗时或耗CPU的前几个方法。这个工具在我们的性能瓶颈分析中很有帮助。
包含四部分,分别是:
a、方法执行本身,不包含调用其他方法所消耗的总时间
b、方法执行本身,不包含其他调用方法所实际使用CPU的时间
c、方法执行本身,包含调用其他方法所消耗的总时间
d、方法执行本身,包含调用其他方法所实际使用CPU的时间
Visual GC
此工具需要安装插件
在工具->插件,可用插件里面可以找到,安装重启即可。
java程序有一个对程序员特别友好的一点是,程序中申请的堆空间不需要程序员手动去释放,而是交给JVM去管理,想要知道一些GC的原理和策略就要学习JVM的一些知识了,下面笔者推荐一篇博客讲的比较好,一篇文章掌握整个JVM,JVM超详细解析!!!_鲑鱼683的博客-CSDN博客_jvm 分析
3.2.2、远程监控区
通过JMX配置的IP和端口即可连接上远程想要连接的进程,监控项和本地一样
3.2.3、快照暂存区
生成的线程dump文件和堆dump都会放到这里,便于后续分析。
4、实践
实际在压测过程中或者性能瓶颈分析的时候,我们可以使用JAVA VisualVM工具来监控CPU的使用情况、内存的使用情况,方法的CPU耗时和总耗时,GC策略的执行情况。
上面的每一个指标背后都有它可分析的逻辑,比如:
在压测中,刚一发压CPU就飙升到100%,此时我们要怎么分析呢,最直观的可以借助上面的工具,去看具体那个方法的CPU使用率比较高,深入去看这个方法,为什么会消耗很高的CPU。再者,我们也要看进程中的线程的状态和堆栈信息,从堆栈信息中能直观的提现出来每个线程在干什么事,比如大量的线程都在竞争锁资源,线程间竞争激励等等。
推荐一篇相关的好文java中WAITING状态的线程为啥还会消耗CPU - 掘金 (juejin.cn)
我们要做的就是储备好相关的知识,借助工具找准切入点,深入分析,探求真相。
版权归原作者 Mysterious superstar 所有, 如有侵权,请联系我们删除。