跳到主要内容

JVM 速查表

快速查阅JVM常用命令、参数和概念。本速查表涵盖了日常开发和运维中最常用的JVM诊断和调优工具。

常用命令速查

进程管理命令

命令用途示例
jps列出Java进程jps -lmv
jstatJVM统计信息jstat -gc <pid> 1000
jmap内存映射jmap -dump:format=b,file=heap.hprof <pid>
jstack线程堆栈jstack -l <pid>
jinfo配置信息jinfo -flags <pid>
jcmd多功能诊断jcmd <pid> help

jstat 常用选项详解

jstat 是监控 JVM 运行状态最常用的命令,可以实时查看 GC、类加载、编译等信息。

# 类加载统计
jstat -class <pid> 1000 5

# 编译统计
jstat -compiler <pid>

# GC统计(每秒刷新,共5次)
jstat -gc <pid> 1000 5

# GC容量信息
jstat -gccapacity <pid>

# GC利用率(百分比形式,更易读)
jstat -gcutil <pid> 1000

# GC原因和统计
jstat -gccause <pid> 1000

# 新生代详细统计
jstat -gcnew <pid>

# 老年代详细统计
jstat -gcold <pid>

jstat -gc 输出列含义

列名含义
S0C/S1CSurvivor 0/1 区容量(KB)
S0U/S1USurvivor 0/1 区已使用(KB)
EC/EUEden 区容量/已使用(KB)
OC/OU老年代容量/已使用(KB)
MC/MU元空间容量/已使用(KB)
YGC/YGCTYoung GC 次数/总时间
FGC/FGCTFull GC 次数/总时间
GCTGC 总时间

jmap 常用选项详解

jmap 用于生成堆转储和分析内存分布,是诊断内存问题的重要工具。

# 查看堆配置信息
jmap -heap <pid>

# 查看对象统计(按大小排序)
jmap -histo <pid> | head -30

# 查看存活对象统计(会触发Full GC)
jmap -histo:live <pid> | head -30

# 生成完整堆转储
jmap -dump:format=b,file=heap.hprof <pid>

# 只转储存活对象(会触发Full GC)
jmap -dump:live,format=b,file=heap_live.hprof <pid>

# 查看类加载器统计
jmap -clstats <pid>

# 查看最终化队列
jmap -finalizerinfo <pid>

jstack 常用选项详解

jstack 用于获取线程堆栈信息,诊断线程死锁、CPU 飙高等问题。

# 打印线程堆栈
jstack <pid>

# 打印额外锁信息
jstack -l <pid>

# 输出到文件
jstack <pid> > thread_dump.txt

# 强制打印(无响应时使用)
jstack -F <pid>

jcmd 完整命令列表

jcmd 是 JDK 7+ 推荐的多功能诊断工具,可以替代多个传统命令。

# 查看所有可用命令
jcmd <pid> help

# JVM版本信息
jcmd <pid> VM.version

# JVM启动参数
jcmd <pid> VM.flags
jcmd <pid> VM.command_line
jcmd <pid> VM.system_properties

# 运行时信息
jcmd <pid> VM.info

# 线程信息
jcmd <pid> Thread.print
jcmd <pid> Thread.print -l # 包含锁信息

# 堆信息
jcmd <pid> GC.heap_info
jcmd <pid> GC.class_histogram
jcmd <pid> GC.heap_dump filename=heap.hprof

# 触发GC
jcmd <pid> GC.run

# 本地内存跟踪
jcmd <pid> VM.native_memory summary
jcmd <pid> VM.native_memory detail

# JIT编译器信息
jcmd <pid> Compiler.CodeHeap_Analytics

# JFR录制
jcmd <pid> JFR.start name=test duration=60s filename=recording.jfr
jcmd <pid> JFR.dump name=test filename=dump.jfr
jcmd <pid> JFR.stop name=test

内存参数

堆内存参数

参数说明示例
-Xms初始堆大小-Xms2g
-Xmx最大堆大小-Xmx2g
-Xmn新生代大小-Xmn512m
-XX:NewRatio新老年代比例-XX:NewRatio=2
-XX:SurvivorRatioEden/Survivor比例-XX:SurvivorRatio=8
-XX:MaxTenuringThreshold对象晋升年龄阈值-XX:MaxTenuringThreshold=15
-XX:PretenureSizeThreshold大对象阈值-XX:PretenureSizeThreshold=3m

堆内存设置原则

  • -Xms-Xmx 设为相同值,避免动态扩容
  • 堆大小通常为物理内存的 50%-80%
  • 新生代一般为堆的 1/3 到 1/4

元空间参数

参数说明示例
-XX:MetaspaceSize初始元空间大小-XX:MetaspaceSize=128m
-XX:MaxMetaspaceSize最大元空间大小-XX:MaxMetaspaceSize=512m
-XX:MinMetaspaceFreeRatioGC后最小空闲比例-XX:MinMetaspaceFreeRatio=40
-XX:MaxMetaspaceFreeRatioGC后最大空闲比例-XX:MaxMetaspaceFreeRatio=70

栈内存参数

参数说明示例
-Xss每个线程的栈大小-Xss1m
-XX:ThreadStackSize线程栈大小(等效-Xss)-XX:ThreadStackSize=1024

栈大小计算

  • 每个线程独立栈空间
  • 总栈内存 = 线程数 × 栈大小
  • 深递归需要更大的栈

直接内存参数

参数说明示例
-XX:MaxDirectMemorySize最大直接内存-XX:MaxDirectMemorySize=256m
-XX:+DisableExplicitGC禁用System.gc()-XX:+DisableExplicitGC

直接内存使用场景

  • NIO ByteBuffer.allocateDirect()
  • Netty 等网络框架
  • 注意:直接内存不足会触发 Full GC

JIT编译器参数

分层编译

参数说明示例
-XX:+TieredCompilation启用分层编译(默认开启)-XX:+TieredCompilation
-XX:TieredStopAtLevel最高编译级别-XX:TieredStopAtLevel=1
-XX:+EnableJVMCI启用JVMCI(Graal编译器)-XX:+EnableJVMCI

编译级别说明

  • Level 0:解释执行
  • Level 1:简单C1编译(快速编译,基本优化)
  • Level 2:受限C1编译
  • Level 3:完整C1编译
  • Level 4:C2编译(深度优化,编译时间长)

编译器优化

参数说明示例
-XX:+PrintCompilation打印编译信息-XX:+PrintCompilation
-XX:+PrintInlining打印内联信息-XX:+PrintInlining
-XX:CompileThreshold触发编译的方法调用次数-XX:CompileThreshold=10000
-XX:OnStackReplacePercentageOSR触发比例-XX:OnStackReplacePercentage=140

代码缓存

参数说明示例
-XX:InitialCodeCacheSize初始代码缓存-XX:InitialCodeCacheSize=160k
-XX:ReservedCodeCacheSize最大代码缓存-XX:ReservedCodeCacheSize=240m
-XX:CodeCacheExpansionSize代码缓存扩展大小-XX:CodeCacheExpansionSize=64k
-XX:+UseCodeCacheFlushing启用代码缓存刷新-XX:+UseCodeCacheFlushing

代码缓存不足症状

  • JIT编译停止
  • 性能下降
  • 警告:CodeCache is full. Compiler has been disabled

线程相关参数

参数说明示例
-Xss线程栈大小-Xss1m
-XX:ParallelGCThreads并行GC线程数-XX:ParallelGCThreads=8
-XX:ConcGCThreads并发GC线程数-XX:ConcGCThreads=4
-XX:+UseThreadPriorities启用线程优先级-XX:+UseThreadPriorities
-XX:ThreadPriorityPolicy线程优先级策略-XX:ThreadPriorityPolicy=1

日志参数

JDK 9+ 统一日志(推荐)

# 基本格式
-Xlog:<selector>[:<output>[:<decorators>][:<output-options>]]

# 常用配置示例

# 输出所有GC日志到文件
-Xlog:gc*:file=/var/log/gc.log:time,level,tags

# 输出GC详情和堆信息
-Xlog:gc*,gc+heap=debug:file=gc.log:time

# 输出类加载信息
-Xlog:class+load=info:file=classload.log

# 输出JIT编译信息
-Xlog:jit+compilation=info:file=jit.log

# 输出GC原因
-Xlog:gc+cause:file=gc.log

# 日志文件滚动(最多5个文件,每个100MB)
-Xlog:gc*:file=/var/log/gc.log:time,level,tags:filecount=5,filesize=100m

常用选择器

选择器说明
gc*所有GC相关日志
gc+heap堆相关信息
gc+causeGC原因
gc+ergo*GC自适应调节
gc+phasesGC各阶段耗时
class+load类加载
jit+compilationJIT编译
os+thread线程相关

JDK 8 及之前(已弃用)

# GC日志
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintGCTimeStamps
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintHeapAtGC
-Xloggc:/path/to/gc.log

垃圾收集器参数

Serial 收集器

单线程收集器,适合小内存、单核环境。

-XX:+UseSerialGC                  # 启用Serial收集器

特点

  • 新生代使用复制算法
  • 老年代使用标记-整理算法
  • 单线程执行,会暂停所有应用线程
  • 简单高效,没有线程交互开销

适用场景

  • 客户端应用
  • 单核服务器
  • 堆内存小于100MB

Parallel 收集器(吞吐量优先)

多线程收集器,关注吞吐量。

-XX:+UseParallelGC                # 新生代使用Parallel
-XX:+UseParallelOldGC # 老年代使用Parallel(JDK8默认配对)
-XX:MaxGCPauseMillis=200 # 最大停顿时间目标
-XX:GCTimeRatio=99 # 吞吐量目标(99表示GC时间占1%)
-XX:+UseAdaptiveSizePolicy # 自适应调节策略
-XX:ParallelGCThreads=8 # GC线程数

吞吐量计算

  • GCTimeRatio=99 表示 GC时间:应用时间 = 1:99
  • 即 GC时间占比 = 1/(1+99) = 1%

G1 收集器(推荐)

JDK 9+ 默认收集器,平衡吞吐量和延迟。

# 基本配置
-XX:+UseG1GC # 启用G1(JDK9+默认)
-XX:MaxGCPauseMillis=200 # 最大停顿时间目标

# Region配置
-XX:G1HeapRegionSize=4m # Region大小(1-32MB,2的幂)

# 年轻代配置
-XX:G1NewSizePercent=5 # 年轻代最小占比
-XX:G1MaxNewSizePercent=60 # 年轻代最大占比

# 并发标记配置
-XX:InitiatingHeapOccupancyPercent=45 # 触发并发标记的堆占用阈值
-XX:G1HeapReservePercent=10 # 保留空间百分比

# Mixed GC配置
-XX:G1MixedGCCountTarget=8 # Mixed GC次数目标
-XX:G1MixedGCLiveThresholdPercent=85 # Region存活对象阈值
-XX:G1HeapWastePercent=5 # 允许浪费空间百分比

# 大对象配置
# 大对象 = 超过Region一半的对象
-XX:G1HeapRegionSize # Region大小影响大对象阈值

# 高级配置
-XX:+UseStringDeduplication # 启用字符串去重
-XX:G1PeriodicGCInterval=0 # 周期性GC间隔(毫秒),0禁用

G1 调优建议

  • 不要设置年轻代大小(-Xmn),让 G1 自动调整
  • 首先调整停顿时间目标
  • 如果停顿时间不达标,再调整其他参数

ZGC 收集器(超低延迟)

JDK 11+ 可用,JDK 21+ 推荐使用分代 ZGC。

# JDK 21+ 推荐:分代ZGC
-XX:+UseZGC -XX:+ZGenerational

# JDK 11-20:非分代ZGC
-XX:+UseZGC

# 内存配置
-XX:SoftMaxHeapSize=4g # 软最大堆大小
-XX:MaxHeapSize=8g # 硬最大堆大小

# 内存归还配置
-XX:-ZUncommit # 禁用内存归还(延迟敏感场景)
-XX:ZUncommitDelay=300 # 内存归还延迟(秒)

# 性能优化
-XX:+UseLargePages # 启用大页
-XX:+AlwaysPreTouch # 预分配内存
-XX:ConcGCThreads=4 # 并发GC线程数

# 其他参数
-XX:ZAllocationSpikeTolerance=2 # 分配峰值容忍度
-XX:ZFragmentationLimit=5 # 最大碎片率百分比

ZGC 选择建议

  • JDK 21+ 务必使用分代ZGC(-XX:+ZGenerational
  • 大内存场景(>32GB)首选
  • 延迟敏感场景首选

Shenandoah 收集器

OpenJDK 的低延迟收集器。

-XX:+UseShenandoahGC              # 启用Shenandoah
-XX:ShenandoahGCMode=normal # GC模式
-XX:ShenandoahGCHeuristics=adaptive # 启发式策略
-XX:ConcGCThreads=4 # 并发GC线程数
-XX:ShenandoahMinRegionSize=256k # 最小Region大小
-XX:ShenandoahMaxRegionSize=32m # 最大Region大小

启发式策略选项

  • adaptive:自适应(默认)
  • compact:更积极回收,适合内存受限环境
  • static:固定阈值
  • aggressive:激进模式,用于测试

GC日志参数

JDK 8及之前

-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintGCCause
-XX:+PrintHeapAtGC
-Xloggc:/path/to/gc.log

JDK 9及之后

-Xlog:gc*:file=/path/to/gc.log:time,level,tags
-Xlog:gc+heap=debug
-Xlog:gc+ergo*=trace

内存区域

运行时数据区

堆内存结构

类加载器层次

垃圾收集器对比

收集器算法适用场景停顿时间特点
Serial复制/标记-整理客户端、小内存(小于100MB)较长简单、单线程
Parallel复制/标记-整理吞吐量优先多线程、高吞吐
CMS标记-清除低延迟(JDK 14已移除)较短并发、有碎片
G1标记-整理+复制服务端通用(默认)小于200ms可预测停顿
ZGC染色指针大内存、超低延迟小于1msJDK 21分代ZGC推荐
ShenandoahBrooks指针低延迟小于10ms并发压缩

常用诊断场景

场景一:内存泄漏诊断

现象:内存持续增长,最终OOM

诊断步骤

# 1. 确认问题:观察老年代使用趋势
jstat -gcutil <pid> 5000 10

# 2. 多次生成堆转储对比
jmap -dump:live,format=b,file=heap1.hprof <pid>
# 等待一段时间后
jmap -dump:live,format=b,file=heap2.hprof <pid>

# 3. 使用MAT分析
# - 打开两个堆转储
# - 对比对象数量变化
# - 查看Dominator Tree
# - 分析Leak Suspects报告
# - 找到GC Root引用链

# 4. 使用jcmd查看对象直方图
jcmd <pid> GC.class_histogram | head -30

MAT 分析要点

  • 关注 Shallow HeapRetained Heap
  • 使用 Path to GC Roots 查找引用链
  • 检查 Thread Stack 查看线程持有的对象

场景二:线程死锁诊断

现象:程序挂起,无响应

诊断步骤

# 1. 使用jstack检测死锁
jstack -l <pid> | grep -A 30 "Found one Java-level deadlock"

# 2. 完整线程转储
jstack -l <pid> > thread_dump.txt

# 3. 使用jcmd获取线程信息
jcmd <pid> Thread.print -l

# 4. 使用VisualVM检测
# - 打开Threads标签页
# - 点击"Detect Deadlock"按钮

死锁输出示例

Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x00007f8b4c001000 (object 0x000000076b5c7d58)
which is held by "Thread-2"
"Thread-2":
waiting to lock monitor 0x00007f8b4c002000 (object 0x000000076b5c7d60)
which is held by "Thread-1"

场景三:CPU 飙高诊断

现象:CPU 使用率异常高

诊断步骤

# 1. 找到高CPU的Java进程
top -H -p <pid>

# 或者使用ps
ps -eLo pid,tid,%cpu,cmd | grep java | sort -k3 -rn | head

# 2. 将线程ID转换为16进制
printf "%x\n" <thread_id>

# 3. 查看对应线程的堆栈
jstack <pid> | grep -A 30 <hex_thread_id>

# 4. 或使用jcmd
jcmd <pid> Thread.print | grep -A 30 <hex_thread_id>

# 5. 使用async-profiler分析CPU热点
./profiler.sh -d 30 -f cpu.html <pid>

Windows 系统诊断

# 使用Process Explorer查看线程
# 或使用PowerShell
Get-Process -Id <pid> | Select-Object -ExpandProperty Threads

# 使用jstack获取线程信息
jstack <pid> > thread_dump.txt

场景四:频繁 Full GC 诊断

现象:频繁 Full GC,响应慢

诊断步骤

# 1. 查看GC统计信息
jstat -gcutil <pid> 1000 20

# 2. 查看GC原因
jstat -gccause <pid> 1000

# 3. 分析GC日志
# 查找Full GC原因:System.gc()、元空间不足、晋升失败等

# 4. 检查是否有显式GC调用
jstack <pid> | grep -B 5 "System.gc"

# 5. 检查元空间使用
jcmd <pid> GC.heap_info | grep -i metaspace

常见 Full GC 原因

  • 老年代空间不足
  • 元空间不足
  • 显式调用 System.gc()
  • RMI 定期 GC
  • 直接内存不足
  • 堆转储时

场景五:OOM 快速诊断

现象:java.lang.OutOfMemoryError

诊断步骤

# 1. 确定OOM类型
# Java heap space: 堆内存不足
# Metaspace: 元空间不足
# GC overhead limit exceeded: GC时间过长
# Direct buffer memory: 直接内存不足

# 2. 开启OOM时自动生成堆转储
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/path/to/dump

# 3. 查看内存使用情况
jmap -heap <pid>

# 4. 对象直方图分析
jmap -histo:live <pid> | head -50

# 5. 本地内存分析(JDK 8u191+)
jcmd <pid> VM.native_memory summary

场景六:应用启动慢诊断

现象:应用启动时间过长

诊断步骤

# 1. 启用启动时间日志
-XX:+PrintFlagsFinal -Xlog:init+redefine=info

# 2. 使用JFR记录启动过程
-XX:StartFlightRecording=duration=60s,filename=startup.jfr

# 3. 分析类加载时间
-Xlog:class+load+time:file=classload.log

# 4. 检查并行加载
-XX:+UseParallelClassLoader

# 5. 使用CDS加速
# 生成共享归档
java -XX:ArchiveClassesAtExit=app.jsa -jar app.jar
# 使用共享归档
java -XX:SharedArchiveFile=app.jsa -jar app.jar

场景七:线程数过多诊断

现象:线程数量异常,内存压力大

诊断步骤

# 1. 查看线程数
jstack <pid> | grep "^\"" | wc -l

# 2. 按线程状态分组统计
jstack <pid> | grep "java.lang.Thread.State" | sort | uniq -c

# 3. 查看线程栈内存占用
# 每个线程栈大小 × 线程数 = 总栈内存

# 4. 使用jcmd查看线程信息
jcmd <pid> Thread.print

# 5. 检查线程池配置
# 关注:核心线程数、最大线程数、队列大小

线程状态说明

状态说明可能原因
RUNNABLE运行中正常
BLOCKED阻塞等待锁锁竞争
WAITING无限等待Object.wait、LockSupport.park
TIMED_WAITING限时等待Thread.sleep、超时等待
NEW新创建未启动线程创建但未start
TERMINATED已终止线程执行完成

性能调优模板

小型应用(< 1GB 堆内存)

适用于开发环境、测试环境、轻量级应用。

java -Xms512m -Xmx512m \
-XX:+UseSerialGC \
-Xlog:gc*:file=gc.log:time \
-jar app.jar

适用场景

  • 开发测试环境
  • 客户端应用
  • 容器资源受限(< 1GB 内存)

吞吐量优先(批处理任务)

适用于批处理、数据分析、后台计算任务。

java -Xmx8g -Xms8g \
-XX:+UseParallelGC \
-XX:NewRatio=1 \
-XX:SurvivorRatio=8 \
-XX:GCTimeRatio=99 \
-XX:+UseAdaptiveSizePolicy \
-XX:ParallelGCThreads=8 \
-Xlog:gc*:file=gc.log:time,level,tags \
-jar app.jar

适用场景

  • 大数据批处理
  • 离线数据分析
  • 报表生成
  • 后台计算任务

关键参数说明

  • NewRatio=1:年轻代和老年代各占一半
  • GCTimeRatio=99:GC时间目标为1%

延迟优先(Web 服务)

适用于 Web 服务、API 网关、微服务。

java -Xmx4g -Xms4g \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=100 \
-XX:InitiatingHeapOccupancyPercent=35 \
-XX:G1HeapRegionSize=8m \
-XX:+UseStringDeduplication \
-Xlog:gc*:file=/var/log/gc.log:time,level,tags:filecount=5,filesize=50m \
-jar app.jar

适用场景

  • Web 服务
  • REST API
  • 微服务
  • 对延迟敏感的应用

关键参数说明

  • MaxGCPauseMillis=100:目标停顿时间100ms
  • InitiatingHeapOccupancyPercent=35:提前触发并发标记

超低延迟(JDK 21+ 推荐)

适用于金融交易、实时游戏、广告竞价等延迟敏感场景。

java -Xmx16g -Xms16g \
-XX:+UseZGC \
-XX:+ZGenerational \
-XX:+UseLargePages \
-XX:+AlwaysPreTouch \
-XX:-ZUncommit \
-XX:ConcGCThreads=8 \
-Xlog:gc*:file=/var/log/gc.log:time,level,tags \
-jar app.jar

适用场景

  • 高频交易系统
  • 实时游戏服务器
  • 广告竞价系统
  • 金融风控系统

关键参数说明

  • ZGenerational:启用分代ZGC(JDK 21+必须)
  • AlwaysPreTouch:启动时预分配内存
  • ZUncommit=false:禁用内存归还

大内存缓存服务

适用于缓存服务、数据索引、内存数据库。

# JDK 21+ 分代ZGC
java -Xmx64g -Xms64g \
-XX:+UseZGC \
-XX:+ZGenerational \
-XX:SoftMaxHeapSize=48g \
-XX:+UseLargePages \
-XX:+AlwaysPreTouch \
-Xlog:gc*:file=/var/log/gc.log:time,level,tags \
-jar cache-service.jar

# 或使用G1(如果延迟要求不那么严格)
java -Xmx64g -Xms64g \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-XX:G1HeapRegionSize=32m \
-XX:InitiatingHeapOccupancyPercent=40 \
-jar cache-service.jar

容器环境(Kubernetes)

适用于云原生、容器化部署。

# JDK 8u191+ / JDK 11+ 容器感知配置
java -XX:+UseContainerSupport \
-XX:MaxRAMPercentage=75.0 \
-XX:InitialRAMPercentage=75.0 \
-XX:MaxMetaspaceSize=256m \
-XX:MaxDirectMemorySize=512m \
-Xss512k \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=100 \
-Xlog:gc*:file=/logs/gc.log:time,level,tags:filecount=5,filesize=50m \
-jar app.jar

Kubernetes 资源配置建议

resources:
limits:
memory: "4Gi"
cpu: "2"
requests:
memory: "3Gi"
cpu: "1"

# JVM 配置说明:
# - 容器限制4GB,JVM堆约75%=3GB
# - 预留1GB给操作系统、元空间、线程栈等
# - 注意:limits和requests不要设置差距过大

容器环境注意事项

  • 使用 UseContainerSupport 自动识别容器资源
  • 使用百分比配置比固定值更灵活
  • 预留至少 25% 内存给非堆开销
  • 注意 CPU 限制影响 GC 线程数

Spring Boot 应用

Spring Boot 应用的推荐配置。

java -Xmx2g -Xms2g \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=100 \
-XX:+AlwaysPreTouch \
-XX:+DisableExplicitGC \
-XX:+UseStringDeduplication \
-Xlog:gc*:file=/var/log/gc.log:time,level,tags:filecount=5,filesize=50m \
-Djava.security.egd=file:/dev/./urandom \
-Dspring.profiles.active=prod \
-jar app.jar

关键参数说明

  • DisableExplicitGC:禁用 System.gc()(Spring 有时会调用)
  • UseStringDeduplication:字符串去重,减少内存占用
  • java.security.egd:解决启动时随机数生成慢的问题

微服务网关

高并发 API 网关配置。

java -Xmx4g -Xms4g \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=50 \
-XX:InitiatingHeapOccupancyPercent=30 \
-XX:G1HeapRegionSize=16m \
-XX:MaxDirectMemorySize=1g \
-XX:+UseStringDeduplication \
-XX:+DisableExplicitGC \
-Xlog:gc*:file=/var/log/gc.log:time,level,tags \
-jar gateway.jar

关键参数说明

  • MaxGCPauseMillis=50:更严格的停顿时间目标
  • MaxDirectMemorySize=1g:网关通常有大量直接内存使用

常用JVM版本

JDK 版本特性对照表

JDK版本发布日期主要特性LTSGC默认
JDK 82014-03Lambda、Stream API、方法引用Parallel
JDK 112018-09HTTP Client、var关键字、ZGC(实验性)G1
JDK 172021-09Sealed Classes、Pattern Matching、RecordG1
JDK 212023-09Virtual Threads、Generational ZGC、Pattern Matching for SwitchG1
JDK 252025-09预计下一个LTS版本✓(预计)G1

LTS 版本选择建议

JDK 8

  • 企业遗留系统、最大兼容性
  • 仍有大量生产环境使用
  • 注意:CMS收集器已移除

JDK 11

  • 过渡选择,稳定且支持新特性
  • HTTP Client API 完善
  • ZGC 开始可用(实验性)

JDK 17

  • 当前主流选择,性能和特性平衡
  • Record 和 Sealed Classes 成熟
  • 建议新项目使用

JDK 21

  • 最新LTS,推荐升级目标
  • Virtual Threads 是重大改进(虚拟线程)
  • 分代 ZGC 是重大改进
  • Spring Boot 3.2+ 完美支持

GC 收集器演进

JDK版本GC 支持情况
JDK 8Serial、Parallel、CMS、G1
JDK 9+移除 CMS(可用但弃用)
JDK 11新增 ZGC(实验性)
JDK 12新增 Shenandoah
JDK 14移除 CMS
JDK 15ZGC 正式可用
JDK 21分代 ZGC 正式可用

迁移注意事项

JDK 8 → JDK 11

  • CMS 收集器不再推荐
  • JavaFX 从 JDK 中移除
  • 需要添加模块依赖(--add-modules

JDK 11 → JDK 17

  • Security Manager 弃用
  • RMI Activation 移除
  • Nashorn JavaScript 引擎移除

JDK 17 → JDK 21

  • Security Manager 更严格的弃用
  • 分代 ZGC 推荐
  • Virtual Threads 需要注意线程池使用方式

诊断命令快速参考

问题诊断速查表

问题现象首选命令辅助命令
内存泄漏jmap -histo:livejmap -dump, MAT
CPU 飙高top -H -p + jstackasync-profiler
线程死锁jstack -lVisualVM
频繁 GCjstat -gcutilGC 日志分析
OOMjmap -heap-XX:+HeapDumpOnOutOfMemoryError
启动慢-Xlog:class+load+timeJFR
类加载问题jstat -class-verbose:class

命令速查卡片

┌─────────────────────────────────────────────────────────────────┐
│ JVM 诊断命令速查 │
├─────────────────────────────────────────────────────────────────┤
│ 进程信息 │
│ jps -lmv 列出所有Java进程 │
│ jinfo -flags <pid> 查看JVM参数 │
│ jcmd <pid> VM.flags 查看所有JVM参数 │
├─────────────────────────────────────────────────────────────────┤
│ 内存诊断 │
│ jstat -gcutil <pid> 1000 实时GC统计 │
│ jmap -heap <pid> 堆配置信息 │
│ jmap -histo <pid> 对象统计 │
│ jmap -dump:file=heap.hprof 生成堆转储 │
│ jcmd <pid> GC.heap_info 堆信息 │
├─────────────────────────────────────────────────────────────────┤
│ 线程诊断 │
│ jstack -l <pid> 线程堆栈(含锁信息) │
│ jcmd <pid> Thread.print 线程信息 │
├─────────────────────────────────────────────────────────────────┤
│ 类加载 │
│ jstat -class <pid> 类加载统计 │
│ jcmd <pid> GC.class_histogram 类直方图 │
├─────────────────────────────────────────────────────────────────┤
│ GC 相关 │
│ jstat -gc <pid> 1000 详细GC统计 │
│ jstat -gccause <pid> GC原因 │
│ jcmd <pid> GC.run 触发GC │
├─────────────────────────────────────────────────────────────────┤
│ JFR 录制 │
│ jcmd <pid> JFR.start name=test duration=60s filename=out.jfr │
│ jcmd <pid> JFR.dump name=test filename=dump.jfr │
│ jcmd <pid> JFR.stop name=test │
└─────────────────────────────────────────────────────────────────┘

参考资源

官方文档

工具下载

进阶学习