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

文章目录

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

1 GC调优概述

1.1 调优指标

1.1.1 吞吐量

1.1.2 延迟

使用GCeasy来进行分析

1.1.3 内存使用量

2 GC调优方法

2.1 发现问题

2.1.1 jstat工具

复制代码
jstat -gc 3785 1000 10

2.1.2 visualvm插件

2.1.3 Prometheus+Grafana

2.1.4 GC Viewer

生成GC日志

复制代码
-XX:+PrintGCDetails -Xloggc:test1.log

生成

shell 复制代码
java -jar gcviewer-1.36.jar test1.log

2.1.5 GCeasy

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

给的相当详细

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 元空间参数

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

2.3.1.3 -Xss 虚拟机栈参数
2.3.1.4 不建议设置参数
2.3.1.5 模板

2.3.2 更换垃圾回收器

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

java 复制代码
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

启动测试脚本

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

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

最后测试g1,在jdk17上

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

2.4 实战

分析出有很多缓存对象

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

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

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

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

2.4.1 总结

相关推荐
学长毕设4 小时前
基于SpringBoot的实验室资产管理系统
java·spring boot·后端
zzu123zsw6 小时前
从臃肿的模板调用到声明式契约:深入 UniHttp 动态代理与多渠道生命周期扩展
java·spring boot·microsoft·unihttp
源码集结号6 小时前
云诊所门诊系统源码,基于SpringBoot+Vue.js架构,支持多租户设计与Docker容器化部署
java·spring boot·源码·医院信息系统·门诊系统·诊所系统
论文复现现场7 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
啃瓜子的松鼠7 小时前
泛微OAe9-后端二开异步调用
java
秋天的怀念_David8 小时前
第二十一夜 · 数字黑洞与西西弗斯的惩罚
java·程序人生·算法
外收内放8 小时前
Python基础语法练习题(73)
java·前端·python
Wang's Blog8 小时前
Java 项目实战: 交友项目 - 环信后台发送消息测试
java·交友
用户3721574261358 小时前
Java 操作 Word 脚注和尾注:添加、读取与删除
java
小嘉丶学长9 小时前
Day14 · 字典与集合
java·开发语言·网络·python·学习·1024程序员节