【地基篇】---Java 8 JVM 知识大纲

基于:JDK 8 / HotSpot VM(2014-03 发布,LTS 长期支持版本);平台 Windows / macOS / Linux

本文是 Java 8 JVM 的知识地图:以「五大功能域」(内存结构、类加载、执行引擎、GC、调优工具)为主线,梳理每个域解决什么问题、核心组件是什么、彼此如何协同,并给出学习路线。适合系统学习 JVM、面试突击、或排查线上问题前先建立全局观。


目录

  1. [定位:为什么学 Java 还要学 JVM](#定位:为什么学 Java 还要学 JVM)
  2. [核心脉络总表:问题 → 解法 → 组件](#核心脉络总表:问题 → 解法 → 组件)
  3. 全景关系图
  4. [功能域一:运行时数据区与 JMM 内存模型](#功能域一:运行时数据区与 JMM 内存模型)
  5. 功能域二:类加载机制
  6. 功能域三:字节码与执行引擎
  7. [功能域四:垃圾回收 GC](#功能域四:垃圾回收 GC)
  8. [功能域五:JVM 参数、监控与排查工具](#功能域五:JVM 参数、监控与排查工具)
  9. [版本演进:JVM 简史与 Java 8 的关键变化](#版本演进:JVM 简史与 Java 8 的关键变化)
  10. 学习路线图
  11. 总结

1. 定位:为什么学 Java 还要学 JVM

1.1 JVM 是什么

  • JVM(Java Virtual Machine) 是运行 Java 字节码的虚拟机,屏蔽操作系统与硬件差异,实现"一次编写,到处运行"。
  • Java 语言与 JVM 是解耦的:Kotlin、Scala、Groovy 同样编译为字节码运行在 JVM 上。
概念 定位 包含内容
JDK 开发工具包 编译器 javac、JVM、核心类库、jps/jstat 等工具
JRE 运行环境 JVM + 核心类库(Java 11 起不再单独发布 JRE)
JVM 虚拟机 类加载子系统、运行时数据区、执行引擎、GC

1.2 为什么要学 JVM

  • 性能调优:吞吐量/响应时间不达标时,需要依据 GC 日志、堆快照定位瓶颈;
  • 故障排查:OOM、CPU 100%、内存泄漏、死锁等线上问题,最终都要落到 JVM 层面分析;
  • 并发正确性:理解 JMM(Java 内存模型)才能写出正确的 volatile、锁、并发容器代码;
  • 面试:JVM 是 Java 后端面试的必考模块。

1.3 为什么以 Java 8 为基准

  • LTS 版本:企业存量系统绝大多数运行在 JDK 8,生产环境排查绕不开;
  • 关键变革节点:永久代移除 → 元空间(Metaspace)、Lambda(invokedynamic)、默认并行回收器、分层编译默认开启,Java 8 是承上启下的分水岭。

关键认知 :JVM 学习应区分规范 (JVM Spec,各厂商通用)与实现(HotSpot,Oracle JDK / OpenJDK 的默认实现)。绝大多数"调优参数、GC 收集器"都是 HotSpot 实现层面的内容,读资料时先分清讨论的是哪一层。


2. 核心脉络总表:问题 → 解法 → 组件

JVM 的每个功能域都源于一个真实问题,先看总表再深入细节:

要解决的问题 解法 核心组件 / 机制 对应功能域
程序运行时数据放哪、为什么会 OOM/栈溢出 定义运行时数据区并做内存管理 堆、虚拟机栈、方法区(元空间)、直接内存 域一 内存结构
多线程下共享变量的可见性/有序性 定义内存模型,规范主内存与工作内存交互 JMM、volatile、happens-before 域一 JMM
.class 文件何时、如何变成内存中的 Class 类生命周期管理 + 双亲委派 类加载器、双亲委派模型、SPI 打破 域二 类加载
字节码如何被执行、如何变快 解释执行 + 即时编译 解释器、C1/C2 编译器、分层编译、栈帧 域三 执行引擎
堆里的垃圾对象何时回收、如何不"卡" 可达性分析 + 分代收集 + 收集器算法 GC Roots、新生代/老年代、CMS/G1 域四 GC
线上如何观测与排查 提供参数开关与命令行工具 -Xmx 等参数、jps/jstat/jmap/jstack/MAT 域五 工具

3. 全景关系图

#mermaid-svg-ktP04eYnyFIdH2fw{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ktP04eYnyFIdH2fw .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ktP04eYnyFIdH2fw .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ktP04eYnyFIdH2fw .error-icon{fill:#552222;}#mermaid-svg-ktP04eYnyFIdH2fw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ktP04eYnyFIdH2fw .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ktP04eYnyFIdH2fw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ktP04eYnyFIdH2fw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ktP04eYnyFIdH2fw .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ktP04eYnyFIdH2fw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ktP04eYnyFIdH2fw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ktP04eYnyFIdH2fw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ktP04eYnyFIdH2fw .marker.cross{stroke:#333333;}#mermaid-svg-ktP04eYnyFIdH2fw svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ktP04eYnyFIdH2fw p{margin:0;}#mermaid-svg-ktP04eYnyFIdH2fw .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ktP04eYnyFIdH2fw .cluster-label text{fill:#333;}#mermaid-svg-ktP04eYnyFIdH2fw .cluster-label span{color:#333;}#mermaid-svg-ktP04eYnyFIdH2fw .cluster-label span p{background-color:transparent;}#mermaid-svg-ktP04eYnyFIdH2fw .label text,#mermaid-svg-ktP04eYnyFIdH2fw span{fill:#333;color:#333;}#mermaid-svg-ktP04eYnyFIdH2fw .node rect,#mermaid-svg-ktP04eYnyFIdH2fw .node circle,#mermaid-svg-ktP04eYnyFIdH2fw .node ellipse,#mermaid-svg-ktP04eYnyFIdH2fw .node polygon,#mermaid-svg-ktP04eYnyFIdH2fw .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ktP04eYnyFIdH2fw .rough-node .label text,#mermaid-svg-ktP04eYnyFIdH2fw .node .label text,#mermaid-svg-ktP04eYnyFIdH2fw .image-shape .label,#mermaid-svg-ktP04eYnyFIdH2fw .icon-shape .label{text-anchor:middle;}#mermaid-svg-ktP04eYnyFIdH2fw .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ktP04eYnyFIdH2fw .rough-node .label,#mermaid-svg-ktP04eYnyFIdH2fw .node .label,#mermaid-svg-ktP04eYnyFIdH2fw .image-shape .label,#mermaid-svg-ktP04eYnyFIdH2fw .icon-shape .label{text-align:center;}#mermaid-svg-ktP04eYnyFIdH2fw .node.clickable{cursor:pointer;}#mermaid-svg-ktP04eYnyFIdH2fw .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ktP04eYnyFIdH2fw .arrowheadPath{fill:#333333;}#mermaid-svg-ktP04eYnyFIdH2fw .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ktP04eYnyFIdH2fw .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ktP04eYnyFIdH2fw .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ktP04eYnyFIdH2fw .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ktP04eYnyFIdH2fw .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ktP04eYnyFIdH2fw .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ktP04eYnyFIdH2fw .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ktP04eYnyFIdH2fw .cluster text{fill:#333;}#mermaid-svg-ktP04eYnyFIdH2fw .cluster span{color:#333;}#mermaid-svg-ktP04eYnyFIdH2fw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ktP04eYnyFIdH2fw .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ktP04eYnyFIdH2fw rect.text{fill:none;stroke-width:0;}#mermaid-svg-ktP04eYnyFIdH2fw .icon-shape,#mermaid-svg-ktP04eYnyFIdH2fw .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ktP04eYnyFIdH2fw .icon-shape p,#mermaid-svg-ktP04eYnyFIdH2fw .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ktP04eYnyFIdH2fw .icon-shape .label rect,#mermaid-svg-ktP04eYnyFIdH2fw .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ktP04eYnyFIdH2fw .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ktP04eYnyFIdH2fw .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ktP04eYnyFIdH2fw :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} JVM
编译期
javac 编译
读取字节码 / 操作数据
JNI
Java 源码 .java
字节码 .class
类加载子系统

加载/验证/准备/解析/初始化
运行时数据区

堆 / 栈 / 元空间 / 直接内存
执行引擎

解释器 + JIT 编译器
垃圾回收器

作用于堆与方法区
本地方法库

C/C++ 库

  • 类加载子系统负责把字节码装进内存;执行引擎负责跑起来;GC 负责回收堆里没用的对象。
  • JMM 描述的是"多线程与运行时数据区(主内存/工作内存)如何交互"的规则层。

一句话概括:字节码是原料,类加载是进货,运行时数据区是仓库,执行引擎是工人,GC 是清仓,调优工具是摄像头。


4. 功能域一:运行时数据区与 JMM 内存模型 ★★★

4.1 运行时数据区总览

区域 线程私有/共享 存储内容 异常
程序计数器 私有 当前线程执行字节码的行号 唯一无异常区域
虚拟机栈 私有 栈帧(局部变量表、操作数栈...) StackOverflowError
本地方法栈 私有 native 方法调用 StackOverflowError
共享 对象实例、数组 OutOfMemoryError
方法区(Java 8:元空间) 共享 类元信息、运行时常量池 OutOfMemoryError
直接内存 --- NIO DirectByteBuffer 引用的堆外内存 OutOfMemoryError

4.2 Java 8 关键变化:永久代 → 元空间

维度 永久代(≤ Java 7) 元空间(Java 8+)
位置 堆内 本地内存(堆外)
容量 固定,-XX:MaxPermSize 默认仅受物理内存限制,-XX:MaxMetaspaceSize
优点 --- 不易 OOM、字符串常量池迁至堆便于回收

4.3 可运行示例:栈溢出与堆溢出

java 复制代码
// StackOverflowError 复现:无线程出口的递归
public class StackOverflowDemo {
    static int depth = 0;
    public static void main(String[] args) {
        try {
            recurse();
        } catch (StackOverflowError e) {
            System.out.println("栈深度: " + depth); // 默认 -Xss 下约 1w+
        }
    }
    static void recurse() { depth++; recurse(); }
}
java 复制代码
// OutOfMemoryError: Java heap space 复现
import java.util.ArrayList;
import java.util.List;
public class HeapOomDemo {
    public static void main(String[] args) {
        List<byte[]> list = new ArrayList<>();
        while (true) list.add(new byte[1024 * 1024]); // 每次 1MB,撑爆堆
    }
}
bash 复制代码
# 堆溢出:-Xmx 调小便于复现
javac HeapOomDemo.java && java -Xmx10m HeapOomDemo

# 栈溢出:调小线程栈
javac StackOverflowDemo.java && java -Xss256k StackOverflowDemo

4.4 JMM:主内存 / 工作内存与 happens-before

  • 所有变量存于主内存 ;线程操作变量时必须拷贝到工作内存再写回。
  • volatile 两条语义:可见性(写立即刷回主内存)+ 禁止指令重排(内存屏障)。
  • happens-before 常用规则速查表:
规则 说明
程序次序 单线程内书写在前先发生
监视器锁 unlock 先于后续 lock
volatile 写先于后续读
传递性 A→B、B→C 则 A→C

相关深度笔记:\[JVM-内存结构-知识点]


5. 功能域二:类加载机制 ★★★

5.1 类生命周期(7 阶段)

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

  • 加载:通过类全限定名找到字节码,生成 java.lang.Class 对象;
  • 准备:为 static 变量分配内存并赋零值;
  • 初始化:真正执行 static 赋值与 static 块(触发时机:new、反射、初始化子类、执行 main 类等)。

5.2 双亲委派模型

#mermaid-svg-3unK0L5K9FQ8B7S5{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3unK0L5K9FQ8B7S5 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3unK0L5K9FQ8B7S5 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3unK0L5K9FQ8B7S5 .error-icon{fill:#552222;}#mermaid-svg-3unK0L5K9FQ8B7S5 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3unK0L5K9FQ8B7S5 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3unK0L5K9FQ8B7S5 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3unK0L5K9FQ8B7S5 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3unK0L5K9FQ8B7S5 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3unK0L5K9FQ8B7S5 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3unK0L5K9FQ8B7S5 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3unK0L5K9FQ8B7S5 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3unK0L5K9FQ8B7S5 .marker.cross{stroke:#333333;}#mermaid-svg-3unK0L5K9FQ8B7S5 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3unK0L5K9FQ8B7S5 p{margin:0;}#mermaid-svg-3unK0L5K9FQ8B7S5 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-3unK0L5K9FQ8B7S5 .cluster-label text{fill:#333;}#mermaid-svg-3unK0L5K9FQ8B7S5 .cluster-label span{color:#333;}#mermaid-svg-3unK0L5K9FQ8B7S5 .cluster-label span p{background-color:transparent;}#mermaid-svg-3unK0L5K9FQ8B7S5 .label text,#mermaid-svg-3unK0L5K9FQ8B7S5 span{fill:#333;color:#333;}#mermaid-svg-3unK0L5K9FQ8B7S5 .node rect,#mermaid-svg-3unK0L5K9FQ8B7S5 .node circle,#mermaid-svg-3unK0L5K9FQ8B7S5 .node ellipse,#mermaid-svg-3unK0L5K9FQ8B7S5 .node polygon,#mermaid-svg-3unK0L5K9FQ8B7S5 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3unK0L5K9FQ8B7S5 .rough-node .label text,#mermaid-svg-3unK0L5K9FQ8B7S5 .node .label text,#mermaid-svg-3unK0L5K9FQ8B7S5 .image-shape .label,#mermaid-svg-3unK0L5K9FQ8B7S5 .icon-shape .label{text-anchor:middle;}#mermaid-svg-3unK0L5K9FQ8B7S5 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3unK0L5K9FQ8B7S5 .rough-node .label,#mermaid-svg-3unK0L5K9FQ8B7S5 .node .label,#mermaid-svg-3unK0L5K9FQ8B7S5 .image-shape .label,#mermaid-svg-3unK0L5K9FQ8B7S5 .icon-shape .label{text-align:center;}#mermaid-svg-3unK0L5K9FQ8B7S5 .node.clickable{cursor:pointer;}#mermaid-svg-3unK0L5K9FQ8B7S5 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3unK0L5K9FQ8B7S5 .arrowheadPath{fill:#333333;}#mermaid-svg-3unK0L5K9FQ8B7S5 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3unK0L5K9FQ8B7S5 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3unK0L5K9FQ8B7S5 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3unK0L5K9FQ8B7S5 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3unK0L5K9FQ8B7S5 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3unK0L5K9FQ8B7S5 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3unK0L5K9FQ8B7S5 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3unK0L5K9FQ8B7S5 .cluster text{fill:#333;}#mermaid-svg-3unK0L5K9FQ8B7S5 .cluster span{color:#333;}#mermaid-svg-3unK0L5K9FQ8B7S5 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3unK0L5K9FQ8B7S5 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3unK0L5K9FQ8B7S5 rect.text{fill:none;stroke-width:0;}#mermaid-svg-3unK0L5K9FQ8B7S5 .icon-shape,#mermaid-svg-3unK0L5K9FQ8B7S5 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3unK0L5K9FQ8B7S5 .icon-shape p,#mermaid-svg-3unK0L5K9FQ8B7S5 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3unK0L5K9FQ8B7S5 .icon-shape .label rect,#mermaid-svg-3unK0L5K9FQ8B7S5 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3unK0L5K9FQ8B7S5 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3unK0L5K9FQ8B7S5 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3unK0L5K9FQ8B7S5 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 加载请求
应用类加载器

classpath
扩展类加载器

jre/lib/ext
启动类加载器

rt.jar

  • 收到加载请求先委派父加载器,父加载不了才自己加载------保证核心类库(如 java.lang.String)不被篡改。
java 复制代码
// 查看一个类的加载器层级(可运行)
public class LoaderDemo {
    public static void main(String[] args) {
        ClassLoader cl = String.class.getClassLoader();
        System.out.println("String 的加载器: " + cl); // null = 启动类加载器(C++ 实现)
        System.out.println("自身类的加载器: " + LoaderDemo.class.getClassLoader());
        // 输出: sun.misc.Launcher$AppClassLoader
    }
}

5.3 打破双亲委派

  • 线程上下文类加载器(Thread Context ClassLoader) :JDBC 等 SPI 场景,核心库反向加载应用类------DriverManager.getConnection() 内部即通过它加载厂商驱动,是学习"打破双亲委派"最经典的案例。

6. 功能域三:字节码与执行引擎

6.1 字节码文件结构与反编译

bash 复制代码
javap -c -v Demo.class   # 查看常量池、方法字节码指令
结构块 说明
魔数 CAFEBABE 文件头标识
版本号 主版本 52 = Java 8
常量池 字面量与符号引用,字节码文件最大结构
访问标志 public/final 等
方法表 含 Code 属性(实际字节码指令)

6.2 执行方式:解释执行 + 即时编译(JIT)

方式 原理 特点
解释执行 逐条翻译字节码执行 启动快、运行慢
JIT(C1/C2) 热点代码编译成本地机器码 启动慢、运行快
  • Java 8 默认开启分层编译(-XX:+TieredCompilation):C1 快速编译保启动,C2 深度优化保峰值;
  • Lambda 依赖 invokedynamic 指令,是 Java 8 字节码层面的重要变化。

6.3 栈帧结构

局部变量表 + 操作数栈 + 动态链接 + 方法返回地址------方法调用本质是栈帧的入栈/出栈,理解栈帧是理解虚拟机栈的关键。


7. 功能域四:垃圾回收 GC ★★★

7.1 判定垃圾:可达性分析

  • GC Roots 包括:虚拟机栈引用、静态变量、常量、JNI 引用等;从根出发不可达的对象即垃圾。

7.2 分代理论与堆结构

区域 默认占比 回收动作
新生代 Eden : S0 : S1 8 : 1 : 1 Minor GC(复制算法)
老年代 新生代 : 老年代 = 1 : 2 Major/Full GC
算法 思路 缺点
标记-清除 标记垃圾后直接清除 内存碎片
复制 存活对象搬到另一半 空间利用率 50%
标记-整理 存活对象向一端移动 移动对象成本高

7.3 Java 8 垃圾收集器速查

收集器 线程 关注点 启用参数
Serial / Serial Old 内存占用小(客户端默认) -XX:+UseSerialGC
ParNew 配合 CMS 的新生代收集器 -XX:+UseParNewGC
Parallel Scavenge / Parallel Old 吞吐量优先(Java 8 服务端默认) -XX:+UseParallelGC
CMS 响应时间优先,低停顿 -XX:+UseConcMarkSweepGC
G1 大堆、可预测停顿(Java 8 可用,9 起默认) -XX:+UseG1GC

关键认知 :Java 8 服务端机器默认 Parallel Scavenge + Parallel Old;CMS 是并发收集器(初始标记/并发标记/重新标记/并发清除四阶段,并发标记使用三色标记法);G1 在 Java 8 已基本成熟但非默认。

7.4 GC 日志(Java 8 风格)

bash 复制代码
# 输出 GC 日志(Java 8 参数风格,9+ 改用 -Xlog:gc)
java -Xms512m -Xmx512m \
     -XX:+PrintGCDetails -XX:+PrintGCDateStamps \
     -Xloggc:gc.log App

# 实时查看 GC 统计(每 1000ms 一次)
jstat -gcutil <pid> 1000

8. 功能域五:JVM 参数、监控与排查工具

8.1 常用参数分类速查

分类 参数 说明
-Xms / -Xmx 初始/最大堆(生产建议相等,避免扩容抖动)
新生代 -Xmn / -XX:NewRatio 新生代大小 / 新生老年代比例
-Xss 线程栈大小
元空间 -XX:MetaspaceSize / -XX:MaxMetaspaceSize 触发 GC 阈值 / 上限
直接内存 -XX:MaxDirectMemorySize NIO 堆外内存上限

8.2 工具速查

工具 用途 典型命令
jps 列出 Java 进程 jps -l
jstat GC/类加载统计 jstat -gcutil 1000
jinfo 查看运行中参数 jinfo -flags
jmap 堆快照 jmap -dump:format=b,file=heap.hprof
jstack 线程栈(死锁排查) jstack | grep -A10 deadlock
jcmd 综合命令 jcmd GC.heap_dump
jvisualvm / MAT 可视化 / 堆分析 分析 heap.hprof 找大对象与泄漏

8.3 OOM 排查对照表

报错信息 原因方向 排查动作
Java heap space 堆不够/泄漏 jmap dump + MAT 分析大对象
Metaspace 类元信息过多(动态代理/热部署) 检查 ClassLoader 泄漏
unable to create new native thread 线程数超限 ulimit -u、线程池大小
Direct buffer memory 堆外内存不足 检查 NIO 使用与 -XX:MaxDirectMemorySize

9. 版本演进:JVM 简史与 Java 8 的关键变化

版本 关键变化
JDK 6 CMS、jmap/jstack 等工具成熟
JDK 7 G1 试验性引入、NIO.2、字符串常量池移入堆
JDK 8(2014-03,LTS) 永久代→元空间、Lambda/invokedynamic、Nashorn JS 引擎、分层编译默认开启、默认 Parallel GC、u20 起字符串去重(-XX:+UseStringDeduplication)
JDK 9+ 模块化、G1 成为默认收集器;11 为下一个 LTS;14 移除 CMS、引入 ZGC/Shenandoah

关键认知:Java 8 是"老参数体系"(PrintGCDetails/Xloggc)与"老收集器组合"(CMS 可用、Parallel 默认)的完整收官版本,新版本的知识(G1 默认、ZGC、-Xlog 日志)都从它演化而来。


10. 学习路线图

#mermaid-svg-FJi91Qv7zmEVrzP4{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-FJi91Qv7zmEVrzP4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-FJi91Qv7zmEVrzP4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-FJi91Qv7zmEVrzP4 .error-icon{fill:#552222;}#mermaid-svg-FJi91Qv7zmEVrzP4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-FJi91Qv7zmEVrzP4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-FJi91Qv7zmEVrzP4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-FJi91Qv7zmEVrzP4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-FJi91Qv7zmEVrzP4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-FJi91Qv7zmEVrzP4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-FJi91Qv7zmEVrzP4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-FJi91Qv7zmEVrzP4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-FJi91Qv7zmEVrzP4 .marker.cross{stroke:#333333;}#mermaid-svg-FJi91Qv7zmEVrzP4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-FJi91Qv7zmEVrzP4 p{margin:0;}#mermaid-svg-FJi91Qv7zmEVrzP4 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-FJi91Qv7zmEVrzP4 .cluster-label text{fill:#333;}#mermaid-svg-FJi91Qv7zmEVrzP4 .cluster-label span{color:#333;}#mermaid-svg-FJi91Qv7zmEVrzP4 .cluster-label span p{background-color:transparent;}#mermaid-svg-FJi91Qv7zmEVrzP4 .label text,#mermaid-svg-FJi91Qv7zmEVrzP4 span{fill:#333;color:#333;}#mermaid-svg-FJi91Qv7zmEVrzP4 .node rect,#mermaid-svg-FJi91Qv7zmEVrzP4 .node circle,#mermaid-svg-FJi91Qv7zmEVrzP4 .node ellipse,#mermaid-svg-FJi91Qv7zmEVrzP4 .node polygon,#mermaid-svg-FJi91Qv7zmEVrzP4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-FJi91Qv7zmEVrzP4 .rough-node .label text,#mermaid-svg-FJi91Qv7zmEVrzP4 .node .label text,#mermaid-svg-FJi91Qv7zmEVrzP4 .image-shape .label,#mermaid-svg-FJi91Qv7zmEVrzP4 .icon-shape .label{text-anchor:middle;}#mermaid-svg-FJi91Qv7zmEVrzP4 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-FJi91Qv7zmEVrzP4 .rough-node .label,#mermaid-svg-FJi91Qv7zmEVrzP4 .node .label,#mermaid-svg-FJi91Qv7zmEVrzP4 .image-shape .label,#mermaid-svg-FJi91Qv7zmEVrzP4 .icon-shape .label{text-align:center;}#mermaid-svg-FJi91Qv7zmEVrzP4 .node.clickable{cursor:pointer;}#mermaid-svg-FJi91Qv7zmEVrzP4 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-FJi91Qv7zmEVrzP4 .arrowheadPath{fill:#333333;}#mermaid-svg-FJi91Qv7zmEVrzP4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-FJi91Qv7zmEVrzP4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-FJi91Qv7zmEVrzP4 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FJi91Qv7zmEVrzP4 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-FJi91Qv7zmEVrzP4 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FJi91Qv7zmEVrzP4 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-FJi91Qv7zmEVrzP4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-FJi91Qv7zmEVrzP4 .cluster text{fill:#333;}#mermaid-svg-FJi91Qv7zmEVrzP4 .cluster span{color:#333;}#mermaid-svg-FJi91Qv7zmEVrzP4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-FJi91Qv7zmEVrzP4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-FJi91Qv7zmEVrzP4 rect.text{fill:none;stroke-width:0;}#mermaid-svg-FJi91Qv7zmEVrzP4 .icon-shape,#mermaid-svg-FJi91Qv7zmEVrzP4 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FJi91Qv7zmEVrzP4 .icon-shape p,#mermaid-svg-FJi91Qv7zmEVrzP4 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-FJi91Qv7zmEVrzP4 .icon-shape .label rect,#mermaid-svg-FJi91Qv7zmEVrzP4 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FJi91Qv7zmEVrzP4 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-FJi91Qv7zmEVrzP4 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-FJi91Qv7zmEVrzP4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 阶段一:内存结构

区域职责 + OOM 复现
阶段二:类加载

双亲委派 + SPI
阶段三:GC

算法 + 收集器 + 日志解读
阶段四:执行引擎

JIT + 字节码
阶段五:实战

调优 + MAT 排查

阶段 内容 产出
① 入门(1 周) 运行时数据区、类加载生命周期、双亲委派 能画内存分区图、手写 OOM/栈溢出 demo
② 进阶(1 周) GC 算法、Java 8 各收集器、JMM/happens-before 能读懂 GC 日志并判断收集器
③ 实战(持续) jstat/jmap/jstack/MAT 排查线上问题 完成一次真实 OOM 或内存泄漏定位

11. 总结

一句话概括:学 Java 8 JVM 就是啃五块骨头------内存结构打底、类加载管入口、执行引擎管运行、GC 管回收、参数工具管观测;五者以"字节码 → 运行时数据区"为主轴串成一张网。

上手路径

  1. 先记住运行时数据区 6 大区域分工(表格即可,不必深究);
  2. 亲手复现 StackOverflowError 与 Java heap space OOM,建立直观体感;
  3. 通读双亲委派源码(ClassLoader#loadClass)------这是最好入门的 JVM 源码;
  4. 跑一个应用,用 jstat + GC 日志观察 Parallel GC 的 Minor GC / Full GC 节奏;
  5. 进阶时转向 CMS/G1 停顿模型、JIT 逃逸分析、JMM 重排序实验。

关注我精彩还在后面......

相关推荐
雾隐隐o11 分钟前
Docker 镜像归档与容器管理
java·docker·eureka
Meta3915 分钟前
Java八股文之Spring Boot 中解决 MySQL 和 Elasticsearch (ES) 的数据一致性问题
java·spring boot·mysql
软件黑马王子18 分钟前
4.单例模式问题2:重复挂载
开发语言·单例模式·c#
quantdash_cc20 分钟前
批量请求和循环请求有什么区别?从 API 请求次数看量化数据获取的工程设计
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
liangbo725 分钟前
01-JVM 内存模型全景
java·jvm
十年Java程序媛25 分钟前
@Async 深度避坑:事务丢失、MDC 上下文丢失、异常静默吞掉完整修复
java·spring boot
qq_4069810326 分钟前
大白话rust系列01注释
开发语言·rust
橘子编程26 分钟前
Java邮件发送全攻略:从入门到实战
java·开发语言·spring boot·spring·spring cloud·maven
阿哉29 分钟前
一次 Lombok 静默失效排查:JDK 23 注解处理默认策略变更引发的满屏「找不到符号」
java