JVM 实战培训课程规划(金融行业场景)
一、培训目标与定位
• 培训目标
○ 建立完整 JVM 知识体系:从原理到实现,聚焦 HotSpot,打通“JVM 结构 → 内存模型 → 类加载 → 执行引擎 → GC → 调优”全链路。
○ 构建可实操的排查与调优体系:围绕金融系统高频问题(OOM、内存泄漏、GC 卡顿、线程异常等),形成标准化排查手册与调优步骤。
○ 提升生产问题处置能力:熟练使用 jps/jstat/jmap/jstack、GC 日志、MAT 等生产工具,能够独立完成一次从“报警 → 定位 → 验证 → 优化 → 回归”的闭环。
○ 支撑 JVM 自主人才梯队建设:沉淀内部可复用的教材、案例、演练任务与规范,为后续内训打基础。
• 适合人群
○ 核心业务系统与中台系统的 Java 开发
○ 应用架构师 / 技术负责人
○ 运维 / SRE / 性能测试工程师(参与 GC 调优与问题排查)
• 基础要求
○ 熟悉 Java 基础语法与集合、多线程基础
○ 有 1 年以上生产项目经验,最好接触过一次以上生产性能/内存问题
二、整体安排概览
• 形式安排
○ 时间:3 天,每天 6 小时左右(建议 9:30–12:00、13:30–17:00)
○ 节奏:上午偏理论体系 + 案例分析,下午偏工具实战 + 上机演练
○ 产出:课程 PPT、讲义 PDF、实验手册、标准排查流程图、典型问题案例库
• 三天主题概览
○ Day 1:JVM 总览与内存模型 / 类加载体系
○ Day 2:GC 算法与 HotSpot 垃圾收集器体系(偏理论 + 案例)
○ Day 3:GC / 内存 / 线程问题排查与性能调优实战(偏实战 + 流程)
Day 1:JVM 总览、运行时内存模型与类加载机制(HotSpot 视角)
上午:JVM 体系与运行时内存模型
1. 金融系统视角下的 JVM 能力边界
○ 金融级系统的特点:强一致性、高可用、低延迟、可审计、可回溯
○ JVM 在金融系统中的角色:在线交易、批量任务、风控引擎、清结算等
○ JVM 相关非功能需求:SLA、响应时间、吞吐量、稳定性与观测性
2. HotSpot JVM 整体架构
○ JVM 规范 vs HotSpot 实现
○ 执行路径:Java 源码 → 字节码 → 即时编译 → 机器码
○ 关键模块:类加载子系统、运行时数据区、执行引擎、GC 子系统
3. 运行时内存模型(HotSpot 重点)
○ 运行时内存划分
▪ 线程私有:程序计数器、虚拟机栈、本地方法栈
▪ 线程共享:堆、方法区(元空间)、运行时常量池
○ 堆结构与分代模型
▪ 新生代(Eden + Survivor)与老年代、Metaspace 基本概念
▪ Generational Hypothesis(代际假说)与对象生命周期
○ 内存溢出场景梳理
▪ 堆内存 OOM、Metaspace OOM、栈溢出 StackOverflowError
▪ 典型业务误用导致的 OOM(大集合缓存、ThreadLocal 泄漏、无界队列等)
4. Java 内存模型(JMM)与并发可见性基础(为 Day3 线程问题埋伏笔)
○ 主内存与工作内存、happens-before、可见性、有序性
○ volatile、synchronized、锁升级对性能与可见性的影响(点到为止)
• 上午小练习 / 讨论
○ 通过简单 Demo 触发:堆 OOM、栈 OOM、Metaspace OOM,对应解读错误信息
○ 结合公司生产事故回顾 1–2 个内存相关事件(由贵司提前提供/匿名化)
下午:类加载机制、类卸载与 Metaspace 问题
5. 类加载机制体系
○ 双亲委派模型原理与金融系统中的典型扩展场景
▪ 自研插件化框架、规则引擎、脚本引擎、SPI、Agent 等
○ ClassLoader 分类与主要实现(Bootstrap、Ext、App、自定义)
○ 类的生命周期:加载 → 链接(验证、准备、解析)→ 初始化 → 使用 → 卸载
6. Metaspace / 常量池问题与排查
○ JDK8+ Metaspace 内存布局与参数配置(MaxMetaspaceSize 等)
○ 典型问题:
▪ 动态代理频繁生成类导致 Metaspace OOM
▪ 频繁热部署 / ClassLoader 泄漏
▪ 大量字符串常量导致内存浪费
○ 案例:某支付渠道系统 Metaspace OOM 事故拆解
▪ 现象:进程多次重启、GC 日志中频繁 Full GC
▪ 工具:jmap、GC 日志、MAT 分析 class 直方图
▪ 根因:自定义 ClassLoader 未被卸载、第三方库使用不当
7. 工具初识:jps / jstat / jmap / jstack 基础用法
○ jps:列出 JVM 进程 ID,结合 -l、-v 查看启动参数
○ jstat:常用场景
▪ jstat -gc/-gcutil 观察堆使用趋势
▪ 新生代 / 老年代占用情况快速判断是否有 GC 风险
○ jmap
▪ -heap 查看堆配置与使用摘要
▪ -histo 快速查看对象分布(Top N 类型)
▪ -dump:live,format=b,file=xxx 生成堆 dump 供 MAT 分析
○ jstack
▪ 线程 Dump 采集与基础解读(死锁、阻塞、频繁切换)
8. 上机实战环节(建议 2~3 个任务)
○ 任务示例:
▪ 编写简单 Demo 动态生成大量类,观察 Metaspace 增长与 OOM
▪ 使用 jps/jstat/jmap 观测一个压测中的 JVM 进程堆使用变化
▪ 使用 jstack 捕获线程快照,识别一个简单的死锁示例
• Day 1 关键收获
○ 能说清楚:HotSpot 运行时内存结构与各区域职责
○ 能用基础工具:jps/jstat/jmap/jstack 完成一次基础的堆 / 线程问题初步定位
○ 对 Metaspace / 类加载相关问题有初步风险意识
Day 2:GC 原理与 HotSpot 垃圾收集器体系(含 GC 日志分析)
上午:GC 算法与收集器体系(理论 + 案例)
9. GC 基本算法与实现策略
○ 标记-清除、标记-整理、复制算法对比
○ 可达性分析(GC Roots)、引用类型(强 / 软 / 弱 / 虚)
○ Stop-The-World(STW)机制与对交易延迟的影响
10. HotSpot 垃圾收集器族谱(以金融系统主流版本为主)
○ 串行 / 并行收集器:Serial、Parallel Scavenge、Parallel Old
○ CMS(若仍有遗留系统)
▪ CMS 运行阶段、并发标记、重标记
▪ CMS 的失败场景:浮动垃圾、内存碎片、promotion failed
○ G1 GC(重点)
▪ Region 概念、年轻代 / 老年代不再物理分区
▪ Mixed GC、Remembered Set、Pause Time 目标
▪ 适用于金融系统的场景与配置思路
○ ZGC / Shenandoah(点到为止,看公司 JDK 版本情况)
11. 金融业务场景下的 GC 策略思考
○ 在线交易 vs 批处理作业 vs 清算对 GC 的不同要求
○ 延迟敏感业务对 STW 的容忍度与峰值 TPS 的关系
○ 常见错误认知:一味追求“无 FullGC” vs 实际业务 SLA
12. 案例讲解:典型 GC 故障
○ 场景 1:交易高峰期频繁 FullGC 导致响应超时
○ 场景 2:CMS promotion failed 触发 Serial Old,响应雪崩
○ 场景 3:G1 配置不当引发频繁 Mixed GC 与长时间 Remark
下午:GC 日志分析 + jstat 结合实战
13. GC 日志参数与输出格式
○ JDK8 / JDK11+ 不同 GC 日志配置方式(-Xloggc / -Xlog:gc*)
○ 关键指标解析:
▪ Young GC / Mixed GC / Full GC 频率与耗时
▪ 各内存区域使用变化、晋升速率、GC Cause
▪ User / Sys / Real 时间及 STW 时长
○ 配合 jstat 长期观察与短期问题定位
14. GC 日志实战分析(以真实或仿真日志为例)
○ 案例 1:Young GC 频繁但停顿较短,吞吐不达标
○ 案例 2:老年代持续增长,偶发超长 FullGC 卡顿
○ 案例 3:Mixed GC 调优前后对比(G1)
15. 工具实践:GC 日志可视化与分析工具
○ 基础命令行分析(grep、自写脚本)
○ 简单介绍一两款 GC 日志可视化工具(如 GCViewer 等)思路(可选)
16. 上机实战环节(建议 2~3 个任务)
○ 任务示例:
▪ 给出一段 GC 日志(CMS / G1),要求参与者:
• 标出 Young / Mixed / FullGC 的发生点与原因
• 估算业务高峰期是否能满足 SLA
▪ 修改 JVM 参数(如 -Xms/-Xmx、G1 相关参数),对比 GC 日志变化
▪ 使用 jstat 持续采样,结合 GC 日志分析一次“堆慢性上涨”的原因
• Day 2 关键收获
○ 能从 GC 日志中读懂:GC 类型、次数、耗时、堆趋势
○ 能根据日志初步判断:是参数问题、对象生命周期问题还是流量/架构问题
○ 对公司主流 GC 策略(如 G1)形成清晰的理解与基本调优原则
Day 3:性能与内存问题排查实战(OOM / 泄漏 / 卡顿 / 线程)
上午:常见生产问题类型与标准排查流程
17. 内存相关问题分类与套路
○ OOM 类型与根因梳理
▪ java.lang.OutOfMemoryError: Java heap space
▪ ...: Metaspace
▪ ...: unable to create new native thread
▪ GC overhead limit exceeded
○ 内存泄漏 vs 内存占用大
▪ 真正的泄漏:对象本不应存活却被错误引用
▪ 正常大对象:确实需要大量内存(大报表、批处理)
18. 内存 / GC 问题排查标准流程(重点输出可复用流程图)
○ 入口:报警来源(APM 指标、JVM 指标、日志告警)
○ 步骤:
i. 通过监控确认问题现象与范围(响应时间、GC 次数、堆使用曲线)
ii. 使用 jps/jstat 快速确认堆/GC 当前状态
iii. 决策是否 dump 堆(jmap,或使用服务框架内置运维命令)
iv. 使用 MAT / GC 日志 交叉验证:
• Who is holding memory?
• 哪些类 / 哪些 Map / 哪些缓存?
v. 结合业务代码与调用链确定根因
vi. 调整方案设计与验证(参数优化 / 代码修复 / 架构改造)
○ 特别强调:生产环境 dump 策略与安全合规要求(脱敏、访问控制、线下分析流程)
19. 线程 / 死锁 / 业务卡顿问题排查流程
○ 线程池使用常见问题:不当核心线程数、无界队列引发 OOM
○ 死锁、活锁、频繁上下文切换
○ 使用 jstack 分析:
▪ 线程状态(RUNNABLE / BLOCKED / WAITING / TIMED_WAITING)
▪ 死锁检测信息、热点线程栈(CPU 飙高场景)
20. 金融系统典型场景拆解(讲师准备 2–3 个真实 / 仿真案例)
○ 案例:核心交易系统在余额批量调整时出现 OOM
○ 案例:风控服务在某规则切换后频繁 FullGC
○ 案例:定时任务线程池配置不当导致 unable to create new native thread
下午:MAT + 工具实战演练 & 体系化总结
21. MAT 堆分析实战
○ MAT 基础视图与概念:
▪ Histogram / Dominator Tree / Top Consumers
▪ Retained Size vs Shallow Size
○ 典型分析路径:
▪ 找 Top N 大对象 → 查看引用链 → 找到责任代码
▪ 找到可疑 ClassLoader / 线程 / 缓存对象
○ 案例引导:
▪ Map 缓存忘记过期策略
▪ ThreadLocal 未手动清理
▪ 监听器 / 回调未注销导致的泄漏
22. 综合演练:从报警到定位到优化(完整闭环)
○ 设计一个接近真实生产的综合实验:
▪ 提供一套压测脚本(或固定请求流量)
▪ 应用在特定场景下出现:
• heap 使用持续上涨 + OOM
• 或 GC 频繁 + 延迟毛刺
▪ 要求学员按流程:
1. 观察监控(提供曲线截图或实时面板)
2. 使用 jps/jstat 定位问题大致方向
3. 使用 jmap 采集 dump
4. 使用 MAT 分析根因
5. 调整代码 / 参数(给出建议或修改 Demo)
6. 再次压测验证效果
○ 小组协作:每组输出一版“排查与调优报告”
23. 构建公司内部 JVM 知识与实战体系(方法论输出)
○ 建议的内部知识库结构:
▪ JVM 基础与运行机制
▪ GC 策略与参数模板(按业务类型)
▪ 典型问题案例库(OOM / 泄漏 / 卡顿 / 线程)
▪ 标准排查流程与工具使用手册
○ 建议的规范 / 模板输出:
▪ JVM 启动参数基线模板(按服务类型划分)
▪ 性能压测报告模板
▪ 生产问题分析报告模板
○ 后续人才梯队建设建议:
▪ 设立 JVM 方向技术负责人 / Champion
▪ 定期组织 GC / 性能复盘分享会
▪ 结合公司实际问题持续更新案例库
24. 培训总结与答疑
○ 回顾三天核心知识点与工具链
○ 针对公司现有系统问题与项目做定向 Q&A
○ 收集参训人员问题,形成 FAQ 文档(后续沉淀)
• Day 3 关键收获
○ 掌握可落地的标准化排查与调优流程
○ 能够针对真实问题完成一轮完整的定位 → 优化 → 验证闭环
○ 明确公司内部 JVM 知识体系与人才梯队建设的路径
三、培训交付物
• 培训交付物
○ 体系化 PPT / 讲义:涵盖三天所有知识点与流程图
○ 实验指南与参考答案:各实战任务的操作步骤与思路
○ 问题排查流程图:
▪ 内存 / GC 问题排查流程
▪ 线程 / 死锁 / 卡顿问题排查流程
○ 典型案例文档:至少 5–8 个典型金融场景案例拆解
○ JVM 参数推荐模板:按应用类型(在线交易、风控、清算、批处理等)