diff --git "a/02-java/jvm/\345\206\205\345\255\230\346\272\242\345\207\272\345\222\214\345\206\205\345\255\230\346\263\204\351\234\262.md" "b/02-java/jvm/\345\206\205\345\255\230\346\272\242\345\207\272\345\222\214\345\206\205\345\255\230\346\263\204\351\234\262.md" index 78e0c840..7102fd45 100644 --- "a/02-java/jvm/\345\206\205\345\255\230\346\272\242\345\207\272\345\222\214\345\206\205\345\255\230\346\263\204\351\234\262.md" +++ "b/02-java/jvm/\345\206\205\345\255\230\346\272\242\345\207\272\345\222\214\345\206\205\345\255\230\346\263\204\351\234\262.md" @@ -83,6 +83,30 @@ Java HotSpot(TM) 64-Bit Server VM -native ERROR -green ERROR +## 面试补充:OOM 与内存泄漏定位 + +OOM 排查第一步不是直接调大内存,而是先判定 OOM 类型。不同类型对应的证据和工具完全不同,方向错了会浪费大量时间。 + +### 常见 OOM 类型 + +`Java heap space` 通常表示堆对象过多或堆设置过小;`GC overhead limit exceeded` 表示堆接近打满且 GC 回收效率极差;`Metaspace` 多与类加载过多或 ClassLoader 泄漏有关;`Direct buffer memory` 要重点看 Netty、NIO、堆外内存;`unable to create new native thread` 则要看线程数、栈大小和系统限制。 + +### 抓现场顺序 + +堆问题优先保留 GC 日志和 Heap Dump,用 MAT 或 JProfiler 看 Dominator Tree、对象数量和引用链。堆外问题要看 NMT、DirectBuffer 使用量和 Netty leak detector。线程问题要结合 `jstack`、线程总数、`ulimit`、容器配额和 `-Xss`。 + +### 泄漏与突增的区别 + +泄漏通常表现为老年代或特定对象数量持续上涨,Full GC 后也降不下来;突增通常与流量峰值、批处理任务、缓存预热、导入导出等事件相关,峰值过后可能恢复。排查时要把内存曲线和发布、流量、任务调度时间线对齐。 + +### 常见泄漏来源 + +常见来源包括静态集合未清理、ThreadLocal 未 remove、监听器或回调未注销、连接和文件句柄未关闭、缓存无上限、ClassLoader 被引用、异步队列堆积。定位时要找“谁持有对象”,而不是只看“对象本身有多大”。 + +### 处理原则 + +生产事故先止血:限流、降级、扩容、重启或摘流量。根因分析再做代码修复、容量评估和监控补齐。只调大 `-Xmx` 可能推迟故障,但不能解决泄漏根因。 + ---