一、JDK自带调优工具jvisualvm
1、启动jvisualvm,打开cmd,输入jvisualvm就会打开jvisualvm工具
启动好是这样的。左侧可以看到本地Test类在运行
双击打开可以看到JVM基本参数设置和运行环境
安装Visual GC插件,打开工具》插件,点击编辑
打开VisualVM网站地址VisualVM: Home
点击Plugins Offlin,选择与自己JDK版本对应的工具
复制插件链接地址
在此处粘贴,点击确定
点击可用插件》点击安装》点击下一步》完成
点击左侧VisualVM》Visual GC,可以看到内存分布情况。整个区域总体分为三部分:
- spaces:代表虚拟机内存分布情况,虚拟机被分为Metaspace(元空间)、 Old、Eden、S0、S1
- graphs:内存使用详细介绍
Compile Time(编译时间):10638 compiles 表示编译总数,23.732s表示编译累计 时间。一个脉冲表示一次JIT编译,窄脉冲表示持续时间短,宽脉冲表示持续时间长。
Class Loader Time(类加载时间): 8214 loaded表示加载类数量, 41 unloaded 表示卸载的类数量,7.858s表示类加载花费的时间
GC Time(GC Time):39 collections表示垃圾收集的总次数,475.316s表示垃圾 收集花费的时间,last cause表示最近垃圾收集的原因
Eden Space(Eden 区):(84.500M表示最大容量,29.000M表示当前容量),8.134M表示当前使用情况,36 collections表示垃圾收集次数,269.053ms表示垃 圾收集花费时间
Survivor 0/Survivor 1(S0和S1区):(28.000M表示最大容量,27.500M表示当前容量),之后的值是20.521M是当前使用情况
Old Gen(老年代):(171.000M表示最大容量,55.000M表示当前容量), 32.225表示当前使用情况,3 collections表示垃圾收集次数 ,206.262ms表示垃圾收集花费时间
Metaspace(元空间):(1.0459.000M表示最大容量,53.289M表示当前容量),50.248M表示当前使用情
- histogramspaces区域:survivor区域参数跟年龄柱状图
二、阿里调优工具Arthas
1、操作系统环境
CentOS Linux release 7.9.2009 64位
2、安装Arthas
官网地址:Arthas,使用如下指令下载arthas-boot.jar包
curl -O https://arthas.aliyun.com/arthas-boot.jar
3、开始使用
在使用Arthas工具前,确保JDK的环境变量是OK的!!!
启动指令:java -jar arthas-boot.jar
第一个红色箭头是启动调优工具Arthas,第二个箭头上一行显示* [1] 11141 Arthas,表示有个Arthas程序在运行,进程号是11141。这是自己编写的代码,类名是Arthas,不要弄混了哟!!!假如有多个程序会列出多个。
1)、输入1表示查看该进程信息,使用dashborad命令可以查看整个进程的运行情况,线程、内存、GC、运行环境信息。会定时刷新。第一部分显示哪个进程占用CPU最高,第二部分显示内存堆eden区、老年代使用情况,第三部分显示程序运行时环境。
2)、使用thread查看程序线程详情
3)、使用thread [pid]查看线程堆栈,如下显示哪一行代码一直占用内存。
4)、使用thread -b查看死锁
5)、使用thread [pid]查看线程堆栈
6)、使用jad Arthas反编译.class文件
7)、查看某个类的成员变量,
ognl @Arthas@hashSet //如果类在编译时加了包名,这里就要写全包名。因为我在编译时把包名注释掉了,所以这里就不用写包名了
8)、动态修改线上代码
ognl '@[email protected]("我是baby")'
9)、退出Arthas
如果只是退出当前的连接,可以用quit
或者exit
命令。Attach 到目标进程上的 arthas 还会继续运行,端口会保持开放,下次连接时可以直接连接上。如果想完全退出 arthas,可以执行stop
命令。
以上只介绍了一些常用指令,更多进阶功能请查看Arthas官方文档。
三、GC日志
1、GC日志打印输出到文件
在java里我们可以通过一些配置将程序运行时的GC日志全部打印出来,然后通过专业的工具进行日志分析,分析GC日志,调优JVM参数。
首先在JVM参数配置GC日志参数:
-Xloggc:./gc-%t.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintGCCause -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M 各参数含义: -Xloggc:./gc-%t.log:指定GC日志文件的名称和位置。%t是一个占位符,将被替换为当前的毫秒级时间。./表示当前目录,文件名以"gc-"开头。 -XX:+PrintGCDetails:启用打印每个GC事件的详细信息,包括GC前后的堆大小、GC的持续时间以及GC的原因。 -XX:+PrintGCDateStamps:启用打印每个GC事件的时间戳。 -XX:+PrintGCTimeStamps:启用打印每个GC事件距离JVM启动的经过时间。 -XX:+PrintGCCause:启用打印每个GC事件的原因,例如通过System.gc()调用触发的全GC,或者通过分配失败触发的并发GC。 -XX:+UseGCLogFileRotation:启用日志文件的轮转,当日志文件达到指定的大小限制时,将关闭该文件并创建一个新的日志文件。这样可以确保GC日志不会占用过多的磁盘空间。 -XX:NumberOfGCLogFiles=10:设置要保留的GC日志文件的最大数量。当达到最大数量时,最旧的日志文件将被删除。 -XX:GCLogFileSize=100M:设置每个GC日志文件的大小。当文件达到此大小时,将关闭该文件并创建一个新的日志文件。该值以兆字节(M)为单位指定。
接着我们结合以上参数启动应用程序
java -jar -Xloggc:./gc-%t.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintGCCause -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M test-server.jar
项目启动成功后,看到一个GC的文件:gc-2023-05-12_09-31-01.log.0.current
2、GC日志文件输出内容的含义
打开GC日志文件可以看到GC回收信息,例如Full GC
我们摘取其中一条来说一下各个含义:
2023-05-12T09:31:02.051+0800: 0.657: [Full GC (Metadata GC Threshold) [PSYoungGen: 6973K->0K(418816K)] [ParOldGen: 104K->6713K(267776K)] 7077K->6713K(686592K), [Metaspace: 20825K->20825K(1069056K)], 0.0140138 secs] [Times: user=0.08 sys=0.03, real=0.01 secs]
2023-05-12T09:31:02.051+0800: //发生Full gc的日期时间
0.657 //JVM启动开始计算到本次触发Full gc经过的时间
[Full GC (Metadata GC Threshold) // 发生Full gc的原因
[PSYoungGen: 6973K->0K(418816K)] //年轻代,6973是触发Full gc之前的年轻代大小,0发生后大小,418816年轻代总大小
[ParOldGen: 104K->6713K(267776K)] //老年代,含义同PSYoungGen
7077K->6713K(686592K) //
[Metaspace: 20825K->20825K(1069056K)] //元空间,
0.0140138 secs] // 该时间点GC总耗时
[Times: user=0.08 sys=0.03, real=0.01 secs] //GC事件的时间统计信息。user
表示用户态的CPU时间,sys
表示内核态的CPU时间,real
表示实际经过的时间。
很明显Full gc回收的原因是因为元空间不够导致,那么针对这个原因,我们可以把元空间设置大一些,例如:
java -jar -Xloggc:./gc-%t.log -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintGCCause -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M test-server.jar
先停掉应用程序,删除原来gc日志文件,使用上面的启动参数重新启动一下,发现没有Full gc了。
3、CMS、G1的GC日志
我们上面说明了JVM默认ParallelGC日志文件格式及内容的含义,在JVM里面还有其他的GC垃圾收集器,例如CMS、G1,这两款垃圾收集器的GC日志文件与ParallelGC大同小异。
使用CMS垃圾收集器,在参数的最后增加-XX:+UseParNewGC -XX:+UseConcMarkSweepGC
java -jar -Xloggc:./gc-%t.log -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintGCCause -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC test-server.jar
查看日志内容:
使用G1垃圾收集器,在参数的最后增加-XX:+UseG1GC
java -jar -Xloggc:./gc-%t.log -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintGCCause -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -XX:+UseG1GC test-server.jar
查看日志内容:
四、GC日志分析工具
在实际的开发中和项目上线后,我们通过肉眼去查看分析GC日志是一件很难且耗时的事,面对巨多的日志文件用眼睛去看,根本就不合适!!!推荐使用专业的工具去分析,例如:gceasy.io,进入官网是这样的
具体使用教程如下:
我们打印GC日志文件后,将GC的日志文件上传的到该网站,它会自动分析,给出分析报告及优化建议(收费的)
点击Analyze,提示分析中,请稍等
结果出来了,JVM内存大小信息,显示年轻代、老年代、元空间等信息
GC停顿时长
堆内存在GC之前和之后的变化
因为收费,如果要查看优化建议需要成为会员。
这里提供2款还不错且免费的GC分析工具:
1.GCViewer
GitHub - microsoft/gctoolkit: Tool for parsing GC logs
最后别忘了JDK自带工具VisualVM,也可以导入日志文件哟!!!
标签:jar,XX,调优,gc,JVM,Arthas,GC,日志 From: https://www.cnblogs.com/shuilangyizu/p/17758951.html