【实战JVM】-实战篇-06-GC调优

作者 : admin 本文共1880个字,预计阅读时间需要5分钟 发布时间: 2024-06-10 共2人阅读

文章目录

  • 1 GC调优概述
    • 1.1 调优指标
      • 1.1.1 吞吐量
      • 1.1.2 延迟
      • 1.1.3 内存使用量
  • 2 GC调优方法
    • 2.1 发现问题
      • 2.1.1 jstat工具
      • 2.1.2 visualvm插件
      • 2.1.3 Prometheus+Grafana
      • 2.1.4 GC Viewer
      • 2.1.5 GCeasy
    • 2.2 常见GC模式
      • 2.2.1 正常情况
      • 2.2.2 缓存对象过多
      • 2.2.3 内存泄漏
      • 2.2.4 持续FullGC
      • 2.2.5 元空间不足导致FullGC
    • 2.3 解决GC问题的手段
      • 2.3.1 优化基础JVM参数
        • 2.3.1.1 -Xmx -Xms 堆参数
        • 2.3.1.2 -XX:MaxMetaspaceSize -XX:MetaspaceSize 元空间参数
        • 2.3.1.3 -Xss 虚拟机栈参数
        • 2.3.1.4 不建议设置参数
        • 2.3.1.5 模板
      • 2.3.2 更换垃圾回收器
    • 2.4 实战
      • 2.4.1 总结

1 GC调优概述

【实战JVM】-实战篇-06-GC调优插图

1.1 调优指标

1.1.1 吞吐量

【实战JVM】-实战篇-06-GC调优插图(1)

【实战JVM】-实战篇-06-GC调优插图(2)

1.1.2 延迟

【实战JVM】-实战篇-06-GC调优插图(3)

使用GCeasy来进行分析

1.1.3 内存使用量

【实战JVM】-实战篇-06-GC调优插图(4)

2 GC调优方法

【实战JVM】-实战篇-06-GC调优插图(5)

2.1 发现问题

2.1.1 jstat工具

【实战JVM】-实战篇-06-GC调优插图(6)

jstat -gc 3785 1000 10

【实战JVM】-实战篇-06-GC调优插图(7)

2.1.2 visualvm插件

【实战JVM】-实战篇-06-GC调优插图(8)

【实战JVM】-实战篇-06-GC调优插图(9)

【实战JVM】-实战篇-06-GC调优插图(10)

2.1.3 Prometheus+Grafana

【实战JVM】-实战篇-06-GC调优插图(11)

2.1.4 GC Viewer

生成GC日志

【实战JVM】-实战篇-06-GC调优插图(12)

-XX:+PrintGCDetails -Xloggc:test1.log

生成

【实战JVM】-实战篇-06-GC调优插图(13)

【实战JVM】-实战篇-06-GC调优插图(14)

java -jar gcviewer-1.36.jar test1.log

【实战JVM】-实战篇-06-GC调优插图(15)

2.1.5 GCeasy

http://gceasy.ycrash.cn/gc-dashboard.jsp

【实战JVM】-实战篇-06-GC调优插图(16)

【实战JVM】-实战篇-06-GC调优插图(17)

给的相当详细

【实战JVM】-实战篇-06-GC调优插图(18)

2.2 常见GC模式

2.2.1 正常情况

【实战JVM】-实战篇-06-GC调优插图(19)

2.2.2 缓存对象过多

【实战JVM】-实战篇-06-GC调优插图(20)

2.2.3 内存泄漏

【实战JVM】-实战篇-06-GC调优插图(21)

2.2.4 持续FullGC

【实战JVM】-实战篇-06-GC调优插图(22)

2.2.5 元空间不足导致FullGC

【实战JVM】-实战篇-06-GC调优插图(23)

2.3 解决GC问题的手段

【实战JVM】-实战篇-06-GC调优插图(24)

2.3.1 优化基础JVM参数

2.3.1.1 -Xmx -Xms 堆参数

【实战JVM】-实战篇-06-GC调优插图(25)

【实战JVM】-实战篇-06-GC调优插图(26)

2.3.1.2 -XX:MaxMetaspaceSize -XX:MetaspaceSize 元空间参数

【实战JVM】-实战篇-06-GC调优插图(27)

所以我们启动程序之后基本都会触发1到2次的由元空间不足引起的FullGC,这是因为-XX:MetaspaceSize触发FullGC最开始的大小可能只有20M,所以会触发1到2次的FullGC,因为是在启动的时候触发的,所以并不会对用户的使用产生影响。

2.3.1.3 -Xss 虚拟机栈参数

【实战JVM】-实战篇-06-GC调优插图(28)

2.3.1.4 不建议设置参数

【实战JVM】-实战篇-06-GC调优插图(29)

【实战JVM】-实战篇-06-GC调优插图(30)

【实战JVM】-实战篇-06-GC调优插图(31)

2.3.1.5 模板

【实战JVM】-实战篇-06-GC调优插图(32)

2.3.2 更换垃圾回收器

第二点减少对象的产生,就涉及内存调优,这个在以前已经讲过了,不再赘述

【实战JVM】-实战篇-06-GC调优插图(33)

private Cache cache = Caffeine.newBuilder().weakKeys().softValues().build();

软引用+弱引用最大程度保证缓存不会溢出

先测试jdk8自带ps+po

-Xms4g -Xmx4g -Xss256k -XX:MaxMetaspaceSize=512m  -XX:+DisableExplicitGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:/test.hprof  -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps

启动测试脚本

【实战JVM】-实战篇-06-GC调优插图(34)

50并发下最大的响应时间是280ms,最后总结,并发越高,fullgc时间越长,因为创建对象速度快,可能刚刚释放,又要创建又要fullgc

再测试parnew+cms

-Xms4g -Xmx4g -Xss256k -XX:MaxMetaspaceSize=512m  -XX:+DisableExplicitGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:/test.hprof  -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseParNewGC -XX:+UseConcMarkSweepGC

【实战JVM】-实战篇-06-GC调优插图(35)

50并发下最大的响应时间是220ms,其实都差不多

最后测试g1,在jdk17上

【实战JVM】-实战篇-06-GC调优插图(36)

【实战JVM】-实战篇-06-GC调优插图(37)

平均不到100ms,差距还是非常明显的。

2.4 实战

【实战JVM】-实战篇-06-GC调优插图(38)

分析出有很多缓存对象

如果想要生成内存快照时不做fullgc,则需要通过jmap来保存,去掉live即可

jmap -dump:format=b,file=/home/jvm/dump/jvm-optimize-jmap.hprof 29317

但是mat分析时还是会自动把能回收的对象排除在外,所以我们需要

【实战JVM】-实战篇-06-GC调优插图(39)

找到了482M的对象,本应该是被回收的,但是这些数组已经不在gcroot的引用链上了,所以用回溯找是没法找到的

【实战JVM】-实战篇-06-GC调优插图(40)

【实战JVM】-实战篇-06-GC调优插图(41)

【实战JVM】-实战篇-06-GC调优插图(42)

【实战JVM】-实战篇-06-GC调优插图(43)

【实战JVM】-实战篇-06-GC调优插图(44)

2.4.1 总结

【实战JVM】-实战篇-06-GC调优插图(45)

【实战JVM】-实战篇-06-GC调优插图(46)

本站无任何商业行为
个人在线分享 » 【实战JVM】-实战篇-06-GC调优
E-->