类加载与双亲委派
为什么 JDBC 驱动不需要 Class.forName() 了?为什么同一个 jar 包在两个 ClassLoader 中加载会报 ClassCastException?答案都在类加载机制里。 一、类加载的 7 个阶段 1.1 加载 → 验证 → 准备 → 解析 → 初始化 → 使用 → 卸载 1.2 哪些阶段是交叉进行的 1.3 类加载的触发时机——主动引用 vs 被动引用 二、类加载器层次结构 2.1 Bootstrap ClassLoader——加载 <JAVA_HOME>/lib 2.2 Extension ClassLoader(JDK 8)→ Platfo...
线上 Full GC 频繁问题排查
凌晨告警群炸了——接口响应超时,服务器 CPU 飙到 300%。登录一看,Full GC 每 5 秒一次。本文还原完整的排查和修复过程。 一、告警与现场 1.1 从监控看异常——CPU 飙升、接口 RT 暴涨、GC 频率异常 1.2 保留现场的三板斧——jstack / jmap / jstat 二、GC 日志解读 2.1 开启 GC 日志 -Xlog:gc*(JDK 9+)vs -XX:+PrintGCDetails(JDK 8) 2.2 GC 日志字段逐一解析 2.3 GC Easy / GC Viewer 可视化分析 2.4 案例日志:每 5 秒...
JVM 垃圾回收器详解
JVM 垃圾收集器发展史就是一部低延迟优化史。从单线程到并发,从分代到分区,每一代 GC 都在解决什么问题? 一、垃圾回收理论基础 1.1 标记阶段——可达性分析 1.2 清除阶段——标记-清除、标记-整理、标记-复制 1.3 分代收集理论——弱分代假说与跨代引用假说 1.4 记忆集(Remembered Set)与卡表(Card Table) 二、Serial / Serial Old——最早的收集器 2.1 单线程工作的原理 2.2 Stop The World(STW)的全过程 2.3 适用场景——桌面应用、单核服务器 三、ParNew——Serial 的多线程版...
JVM 内存模型详解
一个请求打到服务器上,JVM 各块内存区域分别承担了什么角色?线程共享和线程私有的边界在哪? 一、JVM 运行时数据区全景 1.1 五大区域概览图:堆、方法区、虚拟机栈、本地方法栈、程序计数器 1.2 线程共享 vs 线程私有的划分逻辑 二、程序计数器 2.1 为什么需要程序计数器——CPU 时间片轮转 2.2 线程切换后的字节码”断点”恢复 2.3 唯一不会 OOM 的区域 三、Java 虚拟机栈 3.1 栈帧结构:局部变量表、操作数栈、动态链接、返回地址 3.2 局部变量表——基本类型 vs 对象引用 3.3 栈的大小设置 -Xss 及 StackOverflowError ...
Java 对象生命周期
从 new 关键字到被 GC 回收,一个 Java 对象在 JVM 中经历了什么? 一、对象的诞生:new 关键字背后 1.1 类加载检查——符号引用解析为直接引用 1.2 内存分配策略——指针碰撞 vs 空闲列表 1.3 TLAB(线程本地分配缓冲)——减少并发竞争 1.4 初始化零值——为什么字段有默认值 1.5 对象头设置——Mark Word 里存了什么 1.6 <init> 方法执行——构造器的调用时机 二、对象的内存布局 2.1 对象头(Mark Word + Klass Pointer)——32 位 vs 64 位 JVM 的区别 2.2 实例数据——字段...