工作中JVM 调优经历

系列导读:本篇将深入讲解 JVM 调优的核心原理及实战过程中注意事项。


文章目录

    • [一、JVM 内存模型](#一、JVM 内存模型)
      • [1.1 内存结构](#1.1 内存结构)
      • [1.2 内存参数](#1.2 内存参数)
    • 二、垃圾回收器
      • [2.1 GC 对比](#2.1 GC 对比)
      • [2.2 G1 配置示例](#2.2 G1 配置示例)
      • [2.3 ZGC 配置示例](#2.3 ZGC 配置示例)
    • 三、调优主要参数
      • [3.1 内存配置](#3.1 内存配置)
      • [3.2 GC 配置](#3.2 GC 配置)
      • [3.3 日志配置](#3.3 日志配置)
    • 四、问题诊断
      • [4.1 常用工具](#4.1 常用工具)
      • [4.2 OOM 排查](#4.2 OOM 排查)
      • [4.3 CPU 飙高排查](#4.3 CPU 飙高排查)
    • 五、实战案例
      • [5.1 案例:Full GC 频繁](#5.1 案例:Full GC 频繁)
      • [5.2 案例:内存泄漏](#5.2 案例:内存泄漏)
    • 总结

一、JVM 内存模型

1.1 内存结构

复制代码
┌─────────────────────────────────────────────────────────────┐
│                    JVM 内存结构                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────────────────────────────────────────────┐    │
│  │                    堆 (Heap)                        │    │
│  │  ┌─────────────┐  ┌─────────────┐                   │    │
│  │  │  新生代      │  │   老年代    │                   │    │
│  │  │ Eden+Survivor│  │  (Old)     │                   │    │
│  │  └─────────────┘  └─────────────┘                   │    │
│  └─────────────────────────────────────────────────────┘    │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐    │
│  │                 方法区 (Metaspace)                   │   │
│  └─────────────────────────────────────────────────────┘    │
│                                                             │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐        │
│  │ 程序计数器│ │虚拟机栈  │ │本地方法栈 │ │ 直接内存  │        │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

JVM 内存结构(分代模型)图:

1.2 内存参数

参数 说明
-Xms 初始堆大小
-Xmx 最大堆大小
-Xmn 新生代大小
-XX:MetaspaceSize 元空间初始大小
-XX:MaxMetaspaceSize 元空间最大大小

二、垃圾回收器

2.1 GC 对比

GC 说明 适用场景
Serial 单线程 客户端
Parallel 多线程 吞吐优先
CMS 并发标记清除 低延迟
G1 分区收集 大堆、低延迟
ZGC 并发整理 超大堆、极低延迟

2.2 G1 配置示例

bash 复制代码
# G1 GC 配置
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:G1HeapRegionSize=16m
-XX:InitiatingHeapOccupancyPercent=45
-XX:G1ReservePercent=10

2.3 ZGC 配置示例

bash 复制代码
# ZGC 配置 (JDK 15+)
-XX:+UseZGC
-XX:ZCollectionInterval=5
-XX:ZAllocationSpikeTolerance=5
-XX:+UnlockDiagnosticVMOptions
-XX:+ZProactive

JVM 垃圾回收器(GC)对比与选型图:

三、调优主要参数

3.1 内存配置

bash 复制代码
# 推荐配置
-Xms4g                          # 初始堆 = 最大堆
-Xmx4g                          # 避免动态扩容
-Xmn2g                          # 新生代 = 堆的 50%
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
-XX:+UseCompressedOops          # 压缩指针
-XX:+UseCompressedClassPointers

3.2 GC 配置

bash 复制代码
# G1 GC 完整配置
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:G1HeapRegionSize=16m
-XX:InitiatingHeapOccupancyPercent=45
-XX:G1ReservePercent=10
-XX:G1NewSizePercent=5
-XX:G1MaxNewSizePercent=60
-XX:G1HeapWastePercent=5
-XX:G1MixedGCCountTarget=8
-XX:G1MixedGCLiveThresholdPercent=85

3.3 日志配置

bash 复制代码
# GC 日志 (JDK 11+)
-Xlog:gc*:file=gc.log:time,level,tags:filecount=5,filesize=10m

四、问题诊断

4.1 常用工具

工具 说明
jstat GC 统计
jmap 内存映射
jstack 线程栈
jinfo JVM 信息
VisualVM 可视化分析
Arthas 在线诊断

4.2 OOM 排查

bash 复制代码
# 导出堆转储
jmap -dump:format=b,file=heap.hprof <pid>

# 分析堆转储
# 使用 MAT 或 VisualVM 分析

4.3 CPU 飙高排查

bash 复制代码
# 查看线程 CPU 使用
top -H -p <pid>

# 导出线程栈
jstack <pid> > thread.log

# 找到高 CPU 线程对应的堆栈
# 线程 ID 转 16 进制
printf "%x\n" <thread_id>

五、实战案例

Linux 下 JVM 调优标准流程图:

5.1 案例:Full GC 频繁

复制代码
问题现象:系统每隔几分钟 Full GC

分析步骤:
1. jstat -gcutil <pid> 1000
2. 发现老年代增长快
3. jmap -histo <pid> 查看对象分布
4. 发现大量大对象

解决方案:
1. 增大堆内存
2. 调整新生代比例
3. 优化代码减少大对象

5.2 案例:内存泄漏

复制代码
问题现象:老年代持续增长,Full GC 无法回收

分析步骤:
1. jmap -dump 导出堆转储
2. MAT 分析 Dominator Tree
3. 找到占用最大的对象
4. 查看 GC Roots

解决方案:
1. 修复代码中的泄漏点
2. 使用 WeakReference 替代强引用

总结

JVM 内存模型 :堆、栈、方法区

垃圾回收器 :G1、ZGC

调优参数 :内存、GC、日志

问题诊断 :OOM、CPU 飙高

实战案例:Full GC、内存泄漏


作者 :刘~浪地球
更新时间:2026-04-15

相关推荐
zhangchaoxies4 小时前
Python Flask路由怎么限制方法_methods列表配置仅允许GET或POST限制接口非法请求
jvm·数据库·python
qq_334563554 小时前
C#怎么实现后台作业调度 C#如何用Quartz.NET配置Cron表达式执行定时调度作业【框架】
jvm·数据库·python
weixin_586061464 小时前
Django怎么实现跨域请求处理_Python配置CORS中间件详解
jvm·数据库·python
2301_803538954 小时前
Pandas 中使用交叉表为分类列生成计数汇总列
jvm·数据库·python
DaqunChen4 小时前
PHP怎么实现单例模式_PHP常用设计模式之单例模式【方法】
jvm·数据库·python
2301_803538954 小时前
Matplotlib 动画中多子图更新失效的解决方案
jvm·数据库·python
hef28812 小时前
如何生成特定SQL的AWR报告_@awrsqrpt.sql深度剖析单条语句性能
jvm·数据库·python
xcjbqd013 小时前
Python API怎么加Token认证_JWT生成与验证拦截器实现
jvm·数据库·python
hef28815 小时前
golang如何使用range over func_golang range over func迭代器使用方法
jvm·数据库·python