连载中 1/20

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

2026-09-11 · 143 阅读 · 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)

热门推荐

连载中 11/22

主从搭建实操:从零配出一主两从

光讲原理不过瘾?手把手搭一主两从:my.cnf 六个参数、复制账号、GTID、CHANGE REPLICATION SOURCE TO、SHOW REPLICA STATUS 验收,附翻车排查清单。

#MySQL#主从复制#GTID#主从搭建#高可用
2026-05-07 · 10101 阅读 · 0 评论 · 0 赞
连载中 16/22

连接池:HikariCP 参数与连接风暴

连接池不是越大越好:8 核机器配 1000 连接反而更慢的数学原理,HikariCP 四个必调参数,maxLifetime 与 wait_timeout 的隐形陷阱。

#MySQL#连接池#HikariCP#maxLifetime#连接风暴
2026-05-10 · 9873 阅读 · 0 评论 · 0 赞
连载中 4/16

缓存穿透:恶意 ID 打穿 MySQL 的四道防线

请求的数据在缓存和数据库里都不存在时,缓存形同虚设。聊聊参数校验、空值缓存、布隆过滤器、限流熔断四道防线的原理与组合打法。

#Redis#缓存穿透#布隆过滤器#高可用
2026-05-16 · 9294 阅读 · 21 评论 · 287 赞