一、什么是 JVM
JVM(Java Virtual Machine,Java 虚拟机)是 Java 实现"一次编写,到处运行"的核心。
作用:
-
运行 Java 字节码(.class 文件)
-
屏蔽底层操作系统差异
-
自动内存管理(GC)
-
提供运行时环境(线程、类加载等)
👉 简单理解:
JVM 就是 Java 程序的"运行引擎"。
二、JVM 整体结构
JVM 主要分为三大部分:
-
类加载子系统
-
运行时数据区(内存结构)
-
执行引擎
三、类加载机制(重点)
1. 类加载流程
一个类从加载到使用,一共经历:
-
加载(Loading)
-
验证(Verification)
-
准备(Preparation)
-
解析(Resolution)
-
初始化(Initialization)
2. 双亲委派模型(面试高频)
类加载器层级:
-
启动类加载器(Bootstrap ClassLoader)
-
扩展类加载器(Extension ClassLoader)
-
应用类加载器(App ClassLoader)
👉 工作流程:
当一个类被加载时:
-
先让父类加载器加载
-
父类加载不了,才自己加载
3. 为什么要双亲委派?
核心作用:
-
防止重复加载
-
保证安全(核心类不被篡改)
👉 例子:
你不能自己写一个 java.lang.String 覆盖系统类。
四、JVM 内存结构(重点中的重点)
JVM 内存分为:
1. 线程私有
-
程序计数器
-
虚拟机栈
-
本地方法栈
2. 线程共享
-
堆(Heap)
-
方法区(JDK8 之后叫元空间 Metaspace)
五、详细内存区域解析
1. 堆(Heap)
👉 最重要区域,存放对象
结构:
-
新生代(Young Generation)
-
Eden区
-
Survivor区(S0、S1)
-
-
老年代(Old Generation)
2. 虚拟机栈
存储:
-
局部变量
-
方法调用
-
栈帧
👉 常见异常:
- StackOverflowError(栈溢出)
3. 方法区(元空间)
存储:
-
类信息
-
常量池
-
静态变量
👉 JDK8 变化:
- 永久代 → 元空间(使用本地内存)
六、对象创建过程(必考)
对象创建流程:
-
类加载检查
-
分配内存(指针碰撞 / 空闲列表)
-
初始化零值
-
设置对象头
-
执行构造方法
七、垃圾回收机制(GC)
1. 什么是 GC
GC(Garbage Collection)用于自动回收不再使用的对象。
2. 如何判断对象死亡?
两种方式:
-
引用计数法(已淘汰)
-
可达性分析(主流)
👉 核心思想:
从 GC Roots 出发,无法到达的对象 = 垃圾
3. 常见 GC Roots
-
栈中引用
-
静态变量
-
常量
-
本地方法引用
八、垃圾回收算法
1. 标记-清除
优点:
- 简单
缺点:
- 内存碎片
2. 复制算法
适用:
- 新生代
特点:
- Eden → Survivor
优点:
- 无碎片
缺点:
- 浪费空间
3. 标记-整理
适用:
- 老年代
特点:
- 标记 + 压缩
九、常见垃圾回收器
1. Serial(单线程)
适合:
- 小型应用
2. ParNew
- 多线程版 Serial
3. CMS(并发标记清除)
特点:
-
低停顿
-
并发执行
缺点:
-
内存碎片
-
已被淘汰
4. G1(主流)
特点:
-
分区回收(Region)
-
可预测停顿时间
-
适合大内存
👉 面试总结:
G1 = 当前主流垃圾回收器
十、JVM 调优(面试加分项)
1. 常见参数
-Xms:初始堆大小
-Xmx:最大堆大小
-Xmn:新生代大小
-XX:+UseG1GC:使用G1
2. 调优思路
-
先监控(jstat、jvisualvm)
-
分析 GC 次数和停顿时间
-
调整堆大小
-
选择合适 GC
十一、常见 JVM 问题
1. OOM(内存溢出)
常见类型:
-
堆内存溢出
-
栈溢出
-
元空间溢出
2. 排查思路
-
dump 内存
-
分析工具(MAT)
-
找大对象
十二、面试高频总结(重点背)
-
JVM 内存结构
-
双亲委派模型
-
GC 算法区别
-
G1 和 CMS 区别
-
对象创建过程
-
OOM 排查
十三、一句话总结
👉 JVM 本质就是:
类加载 + 内存管理 + 垃圾回收 + 执行引擎