《极客时间教程 - 深入浅出 Java 虚拟机》笔记
《极客时间教程 - 深入浅出 Java 虚拟机》笔记
开篇词:JVM,一块难啃的骨头
略
一探究竟:为什么需要 JVM?它处在什么位置?
- JVM(Java Virtual Machine):运行 Java 字节码的虚拟机,针对不同系统实现相同执行结果
- JRE(Java Runtime Environment):运行已编译 Java 程序所需的一切,不能创建新程序
- JDK(Java Development Kit):包含 JRE + 编译器/调试工具,能够创建和编译程序
JDK = JRE + 开发/调试工具
JRE = JVM + Java 类库 + Java 运行库
JVM = 类加载系统 + 运行时内存区域 + 执行引擎

摘自 stackoverflow 高票问题 - What is the difference between JDK and JRE?
大厂面试题:你不得不掌握的 JVM 内存管理



大厂面试题:从覆盖 JDK 的类开始掌握类的加载机制
Java 类的完整生命周期包括以下几个阶段:
- 加载(Loading) - 将 _.java 文件转为 _.class
- 链接(Linking)
- 验证(Verification) - 确保 Class 文件的字节流中包含的信息符合当前虚拟机的要求
- 准备(Preparation) - 为 static 变量在方法区分配内存并初始化为默认值
- 解析(Resolution) - 将常量池的符号引用替换为直接引用的过程
- 初始化(Initialization) - 为类的静态变量赋予正确的初始值,JVM 负责对类进行初始化,主要对类变量进行初始化

类加载器
Bootstrap ClassLoader - 负责加载
<JAVA_HOME>\lib或被-Xbootclasspath指定的路径ExtClassLoader - 负责加载
<JAVA_HOME>\lib\ext或被java.ext.dir指定的路径AppClassLoader - 负责加载
classpath路径自定义类加载器 - 继承自
java.lang.ClassLoader
双亲委派机制 - 除了顶层的启动类加载器以外,其余的类加载器,在加载之前,都会委派给它的父加载器进行加载。

动手实践:从栈帧看字节码是如何在 JVM 中进行流转的


javap - javap 是 JDK 自带的反解析工具。它的作用是将 .class 字节码文件解析成可读的文件格式。
jclasslib - jclasslib 是一个图形化的工具,能够更加直观的查看字节码中的内容。
大厂面试题:得心应手应对 OOM 的疑难杂症

对象生命周期判断
- 引用计数法
- 可达性分析法 - GC Roots
引用类型
- 强引用
- 软引用
- 弱引用
- 虚引用
深入剖析:垃圾回收你真的了解吗?(上)
垃圾回收算法
- 标记-复制 - 效率最高,但浪费大量内存空间
- 标记-清除 - 效率一般,产生大量内存碎片
- 标记-整理 - 效率最差,不浪费空间且消除内存碎片
GC 分代收集:年轻代 GC 使用标记-复制算法;老年代 GC 使用标记-清除/标记-整理算法。
常见 GC 收集器:
- 年轻代:Serial、ParNew、Parallel
- 老年代:Serial Old、Parallel Old、CMS
- 元空间:G1、ZGC

GC 收集器配置参数:
- -XX:+UseSerialGC 年轻代和老年代都用串行收集器
- -XX:+UseParNewGC 年轻代使用 ParNew,老年代使用 Serial Old
- -XX:+UseParallelGC 年轻代使用 ParallelGC,老年代使用 Serial Old
- -XX:+UseParallelOldGC 新生代和老年代都使用并行收集器
- -XX:+UseConcMarkSweepGC,表示年轻代使用 ParNew,老年代的用 CMS
- -XX:+UseG1GC 使用 G1 垃圾回收器
- -XX:+UseZGC 使用 ZGC 垃圾回收器
深入剖析:垃圾回收你真的了解吗?(下)
- Minor GC:发生在年轻代的 GC。
- Major GC:发生在老年代的 GC。
- Full GC:全堆垃圾回收。比如 Metaspace 区引起年轻代和老年代的回收。
CMS 垃圾回收器分为四个阶段:
- 初始标记
- 并发标记
- 重新标记
- 并发清理
CMS 中都会有哪些停顿(STW):
- 初始标记,这部分的停顿时间较短;
- Minor GC(可选),在预处理阶段对年轻代的回收,停顿由年轻代决定;
- 重新标记,由于 preclaen 阶段的介入,这部分停顿也较短;
- Serial-Old 收集老年代的停顿,主要发生在预留空间不足的情况下,时间会持续很长;
- Full GC,永久代空间耗尽时的操作,由于会有整理阶段,持续时间较长。
大厂面试题:有了 G1 还需要其他垃圾回收器吗?
G1 最重要的概念,其实就是 Region。它采用分而治之,部分收集的思想,尽力达到我们给它设定的停顿目标。
案例实战:亿级流量高并发下如何进行估算和调优
GC 指标
- 系统容量(Capacity)
- 延迟(Latency)
- 吞吐量(Throughput)
选择垃圾回收器:
- 堆小(如 100MB)或单核机器 → 串行收集器(
-XX:+UseSerialGC) - 吞吐量优先,对停顿无特殊要求 → 并行收集器(
-XX:+UseParallelGC) - 响应时间优先,停顿敏感 → G1/ZGC/CMS(
-XX:+UseG1GC、-XX:+UseZGC、-XX:+UseConcMarkSweepGC),吞吐量会略低
第 09 讲:案例实战:面对突如其来的 GC 问题如何下手解决
第 10 讲:动手实践:自己模拟 JVM 内存溢出场景
第 11 讲:动手实践:遇到问题不要慌,轻松搞定内存泄漏
jinfo、jstat、jstack、jhsdb(jmap)等是经常被使用的一些工具,尤其是 jmap,在分析处理内存泄漏问题的时候,是必须的。
工具进阶:如何利用 MAT 找到问题发生的根本原因
MAT 是用来分析内存快照的。