JVM调优工具详解及实战应用

目录

1. JVM调优指令

1.1 Jmap

1.1.1 查看历史生成的实例

1.1.2 查看堆信息

1.1.3 查看堆内存

1.2 Jstack

1.2.1 查看进程死锁

1.2.2 找出占用cpu最高的线程堆栈信息

1.3 Jinfo

1.3.1 查看jvm的参数

1.3.2 查看java系统参数

1.4 Jstat

1.4.1 垃圾回收统计

1.4.2 堆内存统计

1.4.3 新生代垃圾回收统计

1.4.4 新生代内存统计

1.4.5 老年代垃圾回收统计

1.4.6 老年代内存统计

1.4.7 元数据空间统计

2. 调优可视化工具

2.1 jvisualvm

3. JVM调优思路

3.1 查看年轻代对象增长的速率

3.2 计算Young GC的触发频率和每次耗时

3.3 计算每次Young GC后有多少对象存活和进入老年代

3.4 计算Full GC的触发频率和每次耗时

4. 调优实战案例


1. JVM调优指令

1.1 Jmap

Jmap命令可以用来查看内存信息,实例个数以及占用内存大小

前置条件

启动一个应用程序

查看应用的进程ID

1.1.1 查看历史生成的实例

jmap -histo 1224  #查看历史生成的实例
jmap -histo:live 1224  #查看当前存活的实例,执行过程中可能会触发一次full gc
jmap -histo 1224 >D:/log.text #查看历史生成的实例且生成文件

1.1.2 查看堆信息

jmap -heap 1224 #查看堆信息

1.1.3 查看堆内存

生成堆内存文件

1. 手动生成文件

jmap -dump:format=b,file=eureka.hprof 1224

2. 设置内存溢出自动导出dump文件

也可以设置内存溢出自动导出dump文件(内存很大的时候,可能会导不出来)
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./   (路径)

然后可以用jvisualvm命令工具导入该dump文件分析

1.2 Jstack

Jstack是用来查看进程信息的指令

>jstack 1224  #jstack 进程id

"Thread-1" 线程名;

prio=0 优先级=0;

tid=0x000000001fa9e000 线程id;

nid=0x28e8  线程对应的本地线程标识nid

java.lang.Thread.State: RUNNABLE 线程状态

1.2.1 查看进程死锁

当程序中出现死锁时,可以通过Jstack定位到死锁的线程。

1.2.2 找出占用cpu最高的线程堆栈信息

1,使用命令top -p ,显示你的java进程的内存情况,pid是你的java进程号,比如19663

0

2,按H,获取每个线程的内存情况

0

3,找到内存和cpu占用最高的线程tid,比如19664

4,转为十六进制得到 0x4cd0,此为线程id的十六进制表示

5,执行 jstack 19663|grep -A 10 4cd0,得到线程堆栈信息中 4cd0 这个线程所在行的后面10行,从堆栈中可以发现导致cpu飙高的调用方法

0

6,查看对应的堆栈信息找出可能存在问题的代码

1.3 Jinfo

查看正在运行的Java应用程序的扩展参数

1.3.1 查看jvm的参数

jinfo -flags 1224  #jinfo -flags 进程id

1.3.2 查看java系统参数

        jinfo -sysprops 进程id

jinfo -sysprops 1224 

1.4 Jstat

jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下:

jstat [-命令选项] [vmid] [间隔时间(毫秒)] [查询次数]

注意:使用的jdk版本是jdk8

1.4.1 垃圾回收统计

 jstat -gc pid 最常用,可以评估程序内存使用及GC压力整体情况

0

  •  S0C:第一个幸存区的大小,单位KB
  • S1C:第二个幸存区的大小
  • S0U:第一个幸存区的使用大小
  • S1U:第二个幸存区的使用大小
  • EC:伊甸园区的大小
  • EU:伊甸园区的使用大小
  • OC:老年代大小
  • OU:老年代使用大小
  • MC:方法区大小(元空间)
  • MU:方法区使用大小
  • CCSC:压缩类空间大小
  • CCSU:压缩类空间使用大小
  • YGC:年轻代垃圾回收次数
  • YGCT:年轻代垃圾回收消耗时间,单位s
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间,单位s
  • GCT:垃圾回收消耗总时间,单位s

1.4.2 堆内存统计

        jstat -gccapacity pid

jstat -gccapacity 1224

  • NGCMN:新生代最小容量
  • NGCMX:新生代最大容量
  • NGC:当前新生代容量
  • S0C:第一个幸存区大小
  • S1C:第二个幸存区的大小
  • EC:伊甸园区的大小
  • OGCMN:老年代最小容量
  • OGCMX:老年代最大容量
  • OGC:当前老年代大小
  • OC:当前老年代大小
  • MCMN:最小元数据容量
  • MCMX:最大元数据容量
  • MC:当前元数据空间大小
  • CCSMN:最小压缩类空间大小
  • CCSMX:最大压缩类空间大小
  • CCSC:当前压缩类空间大小
  • YGC:年轻代gc次数
  • FGC:老年代GC次数

1.4.3 新生代垃圾回收统计

        jstat -gcnew pid

0

  • S0C:第一个幸存区的大小
  • S1C:第二个幸存区的大小
  • S0U:第一个幸存区的使用大小
  • S1U:第二个幸存区的使用大小
  • TT:对象在新生代存活的次数
  • MTT:对象在新生代存活的最大次数
  • DSS:期望的幸存区大小
  • EC:伊甸园区的大小
  • EU:伊甸园区的使用大小
  • YGC:年轻代垃圾回收次数
  • YGCT:年轻代垃圾回收消耗时间

1.4.4 新生代内存统计

0

  • NGCMN:新生代最小容量
  • NGCMX:新生代最大容量
  • NGC:当前新生代容量
  • S0CMX:最大幸存1区大小
  • S0C:当前幸存1区大小
  • S1CMX:最大幸存2区大小
  • S1C:当前幸存2区大小
  • ECMX:最大伊甸园区大小
  • EC:当前伊甸园区大小
  • YGC:年轻代垃圾回收次数
  • FGC:老年代回收次数

1.4.5 老年代垃圾回收统计

0

  • MC:方法区大小
  • MU:方法区使用大小
  • CCSC:压缩类空间大小
  • CCSU:压缩类空间使用大小
  • OC:老年代大小
  • OU:老年代使用大小
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

1.4.6 老年代内存统计

0

  • OGCMN:老年代最小容量
  • OGCMX:老年代最大容量
  • OGC:当前老年代大小
  • OC:老年代大小
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

1.4.7 元数据空间统计

0

  • MCMN:最小元数据容量
  • MCMX:最大元数据容量
  • MC:当前元数据空间大小
  • CCSMN:最小压缩类空间大小
  • CCSMX:最大压缩类空间大小
  • CCSC:当前压缩类空间大小
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

0

  • S0:幸存1区当前使用比例
  • S1:幸存2区当前使用比例
  • E:伊甸园区使用比例
  • O:老年代使用比例
  • M:元数据区使用比例
  • CCS:压缩使用比例
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

2. 调优可视化工具

2.1 jvisualvm

在控制台输入jvisualvm

点击要查看的进程,右侧久可以查看该线程对应的一些信息。

3. JVM调优思路

JVM优化思路其实简单来说就是尽量让每次Young GC后的存活对象小于Survivor区域的50%,都留存在年轻代里。尽量别让对象进入老年代。尽量减少Full GC的频率,避免频繁Full GC对JVM性能的影响。

3.1 查看年轻代对象增长的速率

        可以执行命令 jstat -gc pid 1000 10 (每隔1秒执行1次命令,共执行10次),通过观察EU(eden区的使用)来估算每秒eden大概新增多少对象,如果系统负载不高,可以把频率1秒换成1分钟,甚至10分钟来观察整体情况。注意,一般系统可能有高峰期和日常期,所以需要在不同的时间分别估算不同情况下对象增长速率。

3.2 计算Young GC的触发频率和每次耗时

        知道年轻代对象增长速率我们就能推根据eden区的大小推算出Young GC大概多久触发一次,Young GC的平均耗时可以通过 YGCT/YGC 公式算出,根据结果我们大概就能知道系统大概多久会因为Young GC的执行而卡顿多久。

3.3 计算每次Young GC后有多少对象存活和进入老年代

这个因为之前已经大概知道Young GC的频率,假设是每5分钟一次,那么可以执行命令 jstat -gc pid 300000 10 ,观察每次eden,survivor和老年代使用的变化情况,在每次gc后eden区使用一般会大幅减少,survivor和老年代都有可能增长,这些增长的对象就是每次Young GC后存活的对象,同时还可以看出每次Young GC后进去老年代大概多少对象,从而可以推算出老年代对象增长速率。

3.4 计算Full GC的触发频率和每次耗时

        知道了老年代对象的增长速率就可以推算出Full GC的触发频率了,Full GC的每次耗时可以用公式 FGCT/FGC 计算得出。

4. 调优实战案例

(后续补充)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瑜伽娃娃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值