完整版JVM 深度学习体系(一)

前言

本文档为全网最系统化、无删减、纯干货JVM学习手册,严格按照9大模块编写:JVM架构、运行时数据区、类加载、垃圾回收、字节码与执行引擎、实战调优、工具链、全链路监控、OOM排查。全文适配Java8~Java17,覆盖面试、日常开发、线上故障排查、生产调优,无废话、无删减、可直接保存下载长期学习背诵。

模块一:JVM 整体架构与核心模块

1.1 JVM 定义

JVM(Java Virtual Machine,Java虚拟机):一款抽象的、基于栈式的虚拟机,能够执行Java字节码,屏蔽操作系统底层差异,实现Java跨平台特性。JVM并不局限于Java语言,只要编译为Class字节码的语言(Kotlin、Scala、Groovy)均可运行在JVM之上。

1.2 JVM 整体架构分层

JVM自上而下分为四层架构,完整描述代码从编写到运行的全过程:

  1. 源码层:开发者编写的.java源代码,面向业务逻辑,高级人类可读语言。

  2. 编译层:借助javac前端编译器,将源码编译为平台无关的.class字节码文件,二进制格式,不可直接运行。

  3. 运行层:JVM核心运行环境,包含四大核心模块,负责加载、解析、执行字节码。

  4. 系统层:对接操作系统、CPU、内存、硬件资源,将虚拟机指令翻译为本地硬件指令。

1.3 JVM 四大核心模块(必考)

JVM运行层由四大核心子系统构成,互相配合完成程序运行,是JVM最底层骨架:

1.3.1 类加载子系统

负责读取外部Class字节码文件,加载至JVM内存,生成java.lang.Class对象;完成类的验证、准备、解析、初始化,管控类的整个生命周期。

1.3.2 运行时数据区

JVM内存模型,程序运行时所有数据的存储载体。包含线程私有内存与线程共享内存,是对象、变量、方法执行的内存基础,也是GC、OOM问题的核心区域。

1.3.3 执行引擎

JVM的CPU,负责翻译并执行字节码指令。包含解释器、JIT即时编译器、垃圾回收器,是代码真正执行的核心模块。

1.3.4 本地方法接口(JNI)

打通Java与底层C/C++的桥梁,用于调用操作系统底层资源。Java中标记native的方法均由该模块执行,例如线程、IO、内存操作底层方法。

1.4 跨平台与字节码设计思想

1.4.1 跨平台本质

核心口号:一次编译,到处运行

原理:Java源码仅编译一次生成统一格式的Class字节码,不同操作系统安装对应适配版本的JVM;由JVM屏蔽Windows、Linux、Mac系统指令差异,统一解析执行字节码。

1.4.2 字节码设计思想

  1. 中立性:不属于任何操作系统、CPU架构;

  2. 精简性:指令短小、文件体积小,加载速度快;

  3. 通用性:多语言编译为字节码,实现语言无关性;

  4. 可移植性:任意装有JVM的设备均可运行。

1.5 虚拟机架构分类

1.5.1 基于栈式虚拟机(HotSpot JVM)

执行计算依赖虚拟机内部操作数栈,无硬件寄存器绑定。

优点:跨平台极强、指令简单、移植性好;缺点:执行速度略慢。

1.5.2 基于寄存器式虚拟机

模拟物理CPU寄存器,直接在寄存器中运算。

优点:执行效率高、运算速度快;缺点:平台耦合度高、移植差。代表:Lua、ART。

1.5.3 混合架构虚拟机

结合栈式跨平台优势与寄存器高效执行优势,新版ZGC、OpenJDK均采用混合优化架构。

模块二:运行时数据区(堆、栈、方法区完整版解析)

2.1 内存区域整体划分

2.1.1 线程私有内存(生命周期跟随线程、无GC)

线程私有区域,线程创建分配、线程销毁释放,不存在垃圾回收。包含:程序计数器、虚拟机栈、本地方法栈。

2.1.2 线程共享内存(全局共享、GC管控)

进程级别共享,所有线程均可访问,存在GC回收。包含:Java堆、方法区、运行时常量池、直接内存。

2.2 线程私有区域详解

2.2.1 程序计数器(唯一无OOM区域)

  1. 作用:记录当前线程正在执行的字节码行号;

  2. 特性:线程私有、内存极小、无GC、永远不会发生内存溢出

  3. 使用场景:线程切换后恢复执行位置。

2.2.2 Java虚拟机栈(Java Stack)

  1. 存储内容:每一个方法调用对应一个栈帧

  2. 栈帧组成:局部变量表、操作数栈、动态链接、方法返回地址、附加信息;

  3. 异常类型:

    1. StackOverflowError:栈深度过大(递归死循环);

    2. OOM:不断扩容导致栈内存耗尽;

  4. 生命周期:方法调用入栈,方法执行完毕自动出栈销毁。

2.2.3 本地方法栈

专门服务于Native本地方法,执行C/C++底层代码;异常类型、内存结构与虚拟机栈一致。

2.3 线程共享区域详解

2.3.1 Java堆(Heap,GC主战场)

  1. 存储内容:所有对象实例、数组,唯一存放对象的内存区域;

  2. 内存分区:新生代 + 老年代;

  3. 分区比例:Eden:S0:S1 = 8:1:1;

  4. 区域作用:

    1. Eden区:新建对象存放位置;

    2. Survivor区:存活对象中转、筛选长期存活对象;

    3. 老年代:存放存活时间久、大体积对象;

  5. 调控参数:-Xms、-Xmx、-Xmn;

  6. 溢出异常:Java heap space。

2.3.2 方法区(JDK8永久代→元空间)

  1. 存储内容:类元信息、常量、静态变量、即时编译代码、方法结构;

  2. 版本演变:

    1. JDK1.6及之前:永久代(堆内内存);

    2. JDK1.8:彻底删除永久代,改为元空间Metaspace(本地物理内存)

  3. 溢出场景:大量动态代理、CGLIB生成类、频繁加载Class;

  4. 异常:Metaspace。

2.3.3 运行时常量池

隶属于方法区,存放编译期生成的字面量、符号引用;运行期间可动态放入常量。

2.3.4 直接内存(堆外内存)

  1. 不属于JVM运行时数据区,不受堆内存限制;

  2. 使用场景:NIO、Netty、零拷贝;

  3. 优点:读写速度快、减少内存拷贝;

  4. 异常:Direct buffer memory。

2.4 所有内存区域异常汇总表

  • 程序计数器:无异常;

  • 虚拟机栈:StackOverflowError、栈OOM;

  • 堆:Java heap space;

  • 元空间:Metaspace;

  • 直接内存:Direct buffer memory。

模块三:类加载子系统(5阶段、双亲委派、自定义加载器)

3.1 类完整生命周期(7阶段)

加载 → 验证 → 准备 → 解析 → 初始化 → 使用 → 卸载。

3.2 五大核心加载阶段(重点)

3.2.1 加载阶段

读取磁盘Class二进制文件,加载到内存;在方法区生成Class类对象,保存类结构信息。

3.2.2 验证阶段(安全校验)

四层校验:文件格式验证、元数据验证、字节码验证、符号引用验证;防止恶意字节码破坏虚拟机。

3.2.3 准备阶段

静态变量 分配内存,赋默认初始值(int=0、boolean=false、引用=null),不赋值开发者自定义值。

3.2.4 解析阶段

将代码中的符号引用 (字符串格式)替换为直接内存引用(真实内存地址),为执行做准备。

3.2.5 初始化阶段(唯一主动触发阶段)

执行静态代码块、给静态变量赋予开发者自定义初始值;触发条件:new对象、访问静态方法/静态变量、反射、子类初始化、启动主类。

3.3 四层类加载器层级

  1. 启动类加载器(Bootstrap):C++编写,加载JDK核心依赖rt.jar;

  2. 平台类加载器(Platform):加载系统扩展包;

  3. 应用类加载器(System/App):加载开发者自定义项目类;

  4. 自定义类加载器:开发者手动实现,实现个性化加载逻辑。

3.4 双亲委派模型(面试必考)

3.4.1 执行规则

当类加载器收到加载请求,优先向上委托父加载器加载;父加载器无法加载,自身才加载。加载顺序:启动类加载器→平台→应用→自定义。

3.4.2 核心作用

  1. 安全防护:防止恶意篡改核心类(例如篡改String类);

  2. 类唯一性:保证全局同一个类只加载一次;

  3. 层级隔离:划分系统类与自定义类。

3.4.3 破坏双亲委派三大场景

  1. SPI机制:JDBC驱动;

  2. Tomcat容器:实现Web应用类隔离;

  3. 热部署、热加载:动态替换Class。

3.5 自定义类加载器

3.5.1 实现方式

继承ClassLoader,重写findClass方法,自定义读取Class字节码逻辑。

3.5.2 实战用途

  • Class文件加密解密;

  • 代码热部署、不停机更新;

  • 依赖包隔离、避免类冲突。

模块四:垃圾回收机制(算法、收集器、分代策略)

4.1 对象存活判定方式

4.1.1 引用计数法(废弃)

给对象添加引用计数器,引用+1、失效-1;计数器为0判定回收。缺陷:无法解决循环引用,现代JVM废弃。

4.1.2 可达性分析法(HotSpot主流)

GC Roots为起始节点,向下遍历引用链;不可到达的对象判定为垃圾对象。

4.1.3 可作为GC Roots的对象

  • 虚拟机栈中引用的对象;

  • 静态变量引用对象;

  • 常量引用对象;

  • 本地方法栈Native引用对象。

4.2 Java四大引用体系

  1. 强引用:默认引用,只要引用存在,永远不回收;

  2. 软引用:内存充足不回收,内存不足强制回收;适用缓存;

  3. 弱引用:只要发生GC,必定回收;适用临时缓存;

  4. 虚引用:无引用效果,仅用于监控GC回收状态。

4.3 三大基础垃圾回收算法

4.3.1 标记-清除算法

标记垃圾、统一清除;优点:简单;缺点:产生大量内存碎片、分配效率低。

4.3.2 标记-复制算法

划分同等大小内存,存活对象复制到空闲区域,清空原区域;优点:无内存碎片;缺点:内存直接浪费一半。适用于新生代。

4.3.3 标记-整理算法

标记垃圾、清除后压缩整理内存,存活对象向一端移动;优点:无碎片;缺点:移动成本高。适用于老年代。

4.4 分代收集策略(JVM核心)

  1. 新生代 :对象朝生夕死、存活率极低 → 标记复制算法

  2. 老年代 :对象存活久、存活率高 → 标记清除/标记整理

4.5 主流垃圾收集器大全(对比+适用场景)

4.5.1 新生代收集器

  • Serial:单线程收集、客户端使用、内存小;

  • ParNew:多线程版本Serial,唯一适配CMS;

  • Parallel Scavenge:高吞吐量、后台任务、大数据使用。

4.5.2 老年代收集器

  • Serial Old:单线程老年代收集;

  • Parallel Old:配合Parallel,高吞吐量;

  • CMS:并发低延迟、互联网Web服务、存在内存碎片。

4.5.3 全堆统一收集器(现代主流)

  • G1:分区收集、可预测停顿、JDK9默认、均衡吞吐量与延迟;

  • ZGC:毫秒级超低延迟、超大堆、JDK11+;

  • Shenandoah:开源低延迟收集器。

4.6 GC分类

  • Minor GC:新生代GC、频率高、速度快;

  • Major GC:老年代GC、速度慢;

  • Full GC:全堆+元空间统一回收、耗时极长、线上严禁频繁触发。

模块五:字节码与执行引擎(结构、指令、JIT优化)

5.1 Class字节码文件结构

Class文件为二进制字节流,固定顺序结构:

  1. 魔数:固定0xCAFEBABE,标识Class文件;

  2. 版本号:主次版本,标识JDK编译版本;

  3. 常量池:占用空间最大,存放字符串、符号引用;

  4. 访问标识:标识类、修饰符、权限;

  5. 类索引、父类索引、接口索引;

  6. 字段表:成员变量、静态变量;

  7. 方法表:方法字节码、异常、参数;

  8. 属性表:附加信息,注解、代码行号。

5.2 常用字节码指令

  • 栈操作指令:入栈、出栈;

  • 运算指令:加减乘除、位运算;

  • 跳转指令:if、for、while循环跳转;

  • 对象指令:new、instanceof;

  • 方法调用指令:invokestatic、invokevirtual。

5.3 JVM三大执行引擎

5.3.1 解释器

逐行翻译字节码、边解释边执行;启动速度快、运行速度慢,适合少量代码。

5.3.2 JIT即时编译器(核心优化)

监测热点代码,将高频执行字节码编译为本地机器码,缓存复用,运行速度极快。

  • C1编译器:客户端编译、快速简单优化;

  • C2编译器:服务端编译、深度复杂优化。

5.3.3 混合执行模式

JVM默认模式:解释执行 + JIT编译结合,兼顾启动速度与运行效率。

5.4 JIT五大核心优化手段

  1. 逃逸分析:判断对象是否逃出方法作用域;

  2. 栈上分配:未逃逸对象分配至栈,不占用堆内存;

  3. 标量替换:拆解对象为基础数据,取消对象创建;

  4. 方法内联:合并短小方法,减少调用开销;

  5. 同步消除:去除无竞争锁,优化同步开销。

5.5 JMM Java内存模型

5.5.1 并发三大特性

原子性、可见性、有序性。

5.5.2 volatile关键字

保证可见性、禁止指令重排序;不保证原子性;底层依靠内存屏障实现。

5.5.3 Happens-Before先行发生原则

八大规则,判定多线程内存可见性,无需开发者手动加锁。

模块六:实战调优(参数配置+案例分析)

6.1 核心JVM内存参数

复制代码

-Xms:堆初始内存 -Xmx:堆最大内存(生产必须 Xms=Xmx) -Xmn:新生代内存大小 -XX:SurvivorRatio:伊甸区比例 -XX:MetaspaceSize:元空间初始值 -XX:MaxMetaspaceSize:元空间上限 -XX:MaxDirectMemorySize:直接内存上限

6.2 主流收集器启用参数

复制代码

-XX:+UseConcMarkSweepGC 启用CMS -XX:+UseG1GC 启用G1(JDK9默认) -XX:+UseZGC 启用ZGC(JDK11+) -XX:+PrintGCDetails 打印详细GC日志

6.3 调优三大核心目标

  1. 高吞吐量:大数据、定时任务 → Parallel收集器;

  2. 低延迟:互联网接口、高并发服务 → G1/ZGC;

  3. 通用原则:严控FullGC、减少GC停顿、控制内存占用。

6.4 线上实战调优案例

6.4.1 微服务小堆调优

限制堆内存、使用G1、降低元空间大小,减少资源占用。

6.4.2 定时任务频繁GC优化

增大新生代、提高吞吐量、减少对象晋升老年代。

6.4.3 高并发接口卡顿优化

更换ZGC、降低停顿时间、优化内存屏障。

模块七:JVM工具链(命令行+可视化+Arthas+MAT)

7.1 JDK自带命令行工具(必备)

  1. jps:查看Java进程、进程ID、启动参数;

  2. jstat:实时监控GC次数、占用、类加载、编译统计;

  3. jmap:查看堆内存对象分布、dump堆快照;

  4. jstack:排查线程死锁、CPU飙高、线程阻塞;

  5. jinfo:动态查看、修改虚拟机运行参数;

  6. jcmd:全能命令,整合所有工具功能。

7.2 基础可视化工具

  • JConsole:简易监控、免费、基础指标查看;

  • JVisualVM:全能可视化,监控内存、线程、GC、导出快照。

7.3 线上诊断神器:Arthas(阿里)

生产环境无停机、无侵入诊断工具,企业必备。

  • 查看方法执行耗时、追踪调用链路;

  • 动态查看运行时参数、返回值;

  • 热更新代码、无需重启服务;

  • 监控线程、内存、GC实时状态。

7.4 内存泄漏专用:MAT

专业分析dump堆快照,定位内存泄漏。

  • 统计大对象、冗余对象;

  • 分析对象引用链,找出泄漏源头;

  • 生成泄漏报表、风险提示。

模块八:性能监控(全链路监控方案)

8.1 核心监控指标

8.1.1 内存指标

堆内存使用率、元空间占用、直接内存占用、内存波动。

8.1.2 GC指标

MinorGC次数、FullGC次数、GC停顿耗时、GC吞吐量。

8.1.3 线程指标

活跃线程、阻塞线程、等待线程、死锁线程、峰值线程数。

8.1.4 类加载指标

加载类数量、卸载类数量、元空间增长速率。

8.2 企业级监控架构

SpringBoot + Actuator + Prometheus + Grafana

  1. Actuator:暴露JVM监控端点;

  2. Prometheus:时序数据存储、指标采集;

  3. Grafana:可视化大屏、曲线图、仪表盘。

8.3 线上告警策略

  • 堆内存使用率超过80%告警;

  • 1小时出现多次FullGC告警;

  • 线程阻塞、死锁告警;

  • 元空间持续上涨告警。

模块九:OOM内存溢出(全场景分析+排查流程)

9.1 八大OOM全场景详解

  1. Java heap space:堆内存溢出,大量对象、内存泄漏;

  2. Metaspace:动态类过多、代理频繁、类未卸载;

  3. Direct buffer memory:NIO堆外内存未释放;

  4. StackOverflow:递归死循环、方法嵌套过深;

  5. 无法创建新线程:线程池无限创建、线程无销毁;

  6. 超大数组OOM:一次性申请超大连续内存;

  7. 本地内存溢出:系统物理内存耗尽;

  8. 容器限制OOM:Docker环境内存配额不足。

9.2 高频内存泄漏原因

  • 静态集合长期持有引用;

  • 线程池线程常驻不销毁;

  • 监听器、回调方法未注销;

  • IO流、连接池资源未关闭;

  • 缓存无过期淘汰策略。

9.3 线上标准排查流程(企业通用)

  1. 查看日志,判定OOM异常类型;

  2. jstat持续观察内存、GC走势;

  3. jstack排查线程死锁、阻塞;

  4. jmap导出dump堆快照;

  5. MAT分析引用链、定位泄漏对象;

  6. 代码溯源、修复bug;

  7. 压力测试、验证修复效果。

附录:JVM高频面试总结

  1. 简述JVM四大核心模块?

  2. 运行时数据区划分、各区域作用?

  3. 双亲委派模型原理、作用、破坏场景?

  4. GC可达性分析、GC Roots包含哪些?

  5. CMS、G1、ZGC区别与适用场景?

  6. JIT优化包含哪些手段?

  7. 线上OOM排查完整流程?

  8. 生产环境JVM调优原则?

  9. 内存泄漏与内存溢出区别?

  10. volatile底层原理、内存屏障?

相关推荐
兰令水2 小时前
topcode【随机算法题】【2026.5.17打卡-java版本】
java·算法·leetcode
Geometry Fu2 小时前
《设计模式》2026编程作业汇总
java·c++·设计模式
YOU OU2 小时前
Spring MVC 练习项目
java·后端·spring
wang3zc2 小时前
如何设置密码复杂度策略以约束MongoDB用户的密码强度
jvm·数据库·python
ChoSeitaku2 小时前
02.变量_数据类型转换_运算符
java·大数据·开发语言
微风欲寻竹影2 小时前
队列(Queue)-详解
java·数据结构
想不明白的过度思考者2 小时前
Unity全局事件中心与新版输入架构实现练习——上帝模式与英雄模式的输入系统映射切换
java·unity·架构
小新同学^O^2 小时前
简单学习Spring原理
java·学习·spring
戴西软件3 小时前
戴西软件入选2026年安徽省制造业数智化转型服务商名单
java·大数据·服务器·前端·人工智能