连载中 1/20

为什么 Java 工程师绕不开 JVM:从一次线上 OOM 说起

2026-09-11 · 138 阅读 · 0 评论 · 0 赞

周日早上七点的告警

故事从周日早上七点开始:值班群里 OOM 告警炸了,堆内存 100%,服务挂着几十个线程在哀嚎。值班的同事熟练地重启,服务复活;周一风平浪静,周三同一告警再次响起,又是重启。一个月里这台服务被重启了六次,没人知道它为什么吃内存,只知道重启能续命

这不是段子,是很多团队的日常。会写 Java 和会养 Java 是两回事——代码能跑起来靠的是 IDE 和框架,进程能活得健康靠的是对 JVM 的理解。重启大法的本质,是看不懂病历只管掐人中

JVM 到底管着什么

Java 号称"一次编写,到处运行",但代码从来不是直接跑在操作系统上——你写的每一行都跑在 JVM 这个地盘上。它管三件事:内存(对象分配在哪、什么时候回收)、执行(字节码解释执行还是编译成机器码)、运行时服务(类怎么加载、线程怎么调度)。GC、OOM、StackOverflowError,全藏在这三件事里。

// 用 -Xmx32m 跑这段代码,十秒内进程挂掉
List<byte[]> leak = new ArrayList<>();
while (true) {
    leak.add(new byte[1024 * 1024]);   // 每轮吃掉 1MB,只进不出
}
// 遗言长这样:java.lang.OutOfMemoryError: Java heap space
// 堆栈里往往还留着案发地点——谁在疯狂分配

挂着不可怕,可怕的是看不懂它临终前的遗言。那段 OutOfMemoryError 的堆栈,其实早就把案发地点写在里面了——只是不认识 JVM 的人,把它当成了乱码。

懂 JVM 的三个实际收益

第一,故障定位从"重启续命"变成"十分钟锁定":CPU 飙高、内存泄漏、频繁 Full GC,都有成熟的排查路径,本系列会一篇篇给到。第二,性能优化有了抓手:知道新生代和老年代的分工,才明白缓存为什么不能无上限;理解停顿的来源,才知道该动哪个旋钮。第三,面试不虚——JVM 是后端面试的固定节目,而且面试官最爱追问"你实际排查过什么问题",背概念是糊弄不过去的。

这个系列的路线图

二十篇分五段走:内存与对象(运行时数据区、对象的一生)、类加载(加载五步、双亲委派)、垃圾回收(标记、算法、Serial 到 ZGC)、实战排查(GC 日志、四件套、MAT、OOM 地图、CPU 飙高、内存泄漏)、调优进阶(参数思路、JIT、堆外内存)。

阶段回答的问题篇目
内存与对象内存怎么分、对象怎么生2-3
类加载Class 从哪来、怎么装4-5
垃圾回收谁收、怎么收、谁来收6-10
实战排查出事了怎么查11-16
调优进阶怎么让它跑得更好17-20

先把环境备好

建议统一用 JDK 17 跟做:语法不是重点,重要的是新收集器的默认行为已经变了。装好后把 IDEA 自带的 Profiler 或 JConsole 摸一遍,系列里每个实验都值得亲手跑一次——JVM 的知识不看会忘,跑过一遍就长在身上了。下一篇从地基讲起:运行时数据区,堆和栈到底怎么分,StackOverflowError 和 OOM 为什么报在不同的地方。

503

10 年全栈工程师 · 503咖啡馆主理人

#JVM开篇#OutOfMemory#内存管理#Java运行原理#系列规划

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 5 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞