JJava 知识库
JAVA INTERVIEW

高频面试题

JVM高级约 2 分钟

线上 Java 服务发生 OOM,但流量还在进来,你会按什么顺序止损、取证和定位?

参考回答约 2 分钟 · 口语表达
我的判断

OOM 处理中先保护整体服务并保留证据,再按堆、直接内存、元空间或本地内存分类定位;不能让所有实例同时导出大 dump。

告警后会立即把问题实例从流量池摘下,保留一两个现场实例,其他实例扩容或限流承接流量。先看异常类型、容器是否 OOMKilled、堆占用、GC、线程数和进程 RSS。只有磁盘和停顿风险可接受时,才在单个现场实例获取 heap dump;其余实例用 jcmd GC.class_histogram、NMT 或 JFR 做轻量取证。

不同类型走不同证据:

  • Java heap space:看 dominator、retained size 和对象到 GC Root 的引用链;
  • Direct buffer memory:查 Netty 池、未释放 buffer 和 MaxDirectMemorySize
  • Metaspace:看类数量和 VM.classloader_stats,重点找无法回收的类加载器;
  • 容器被杀但堆不高:对账线程栈、本地库、文件映射和分配器。

修复要回到增长来源:无界缓存加容量和过期、监听器解除引用、批处理改流式。单纯加堆只能延后下一次事故。

排查与恢复时间线从目标到落地
01监控发现内存持续上涨
02JVM 抛 OOM?
03识别 OOM 类型
04检查 OOMKilled 与 RSS
05摘除实例并保存现场
容易答偏踩坑误区
  • 所有 Pod 同时 -XX:+HeapDumpOnOutOfMemoryError 可能瞬间打满共享磁盘。
  • OOM 后立即重启且不留指标。 服务恢复了,但根因也消失了。
  • 只看浅对象大小。 真正需要看对象保留的整棵引用图。