26 面试官问“线上 OOM 你怎么排查“,答不出来的基本都卡在这一步
面试现场面试官问了个很实在的问题。面试官假设线上服务突然抛了 OutOfMemoryError你手上只有一个 PID你怎么查候选人A重启一下——面试官手里的笔停了一下。候选人A赶紧补我是说重启之后加内存把-Xmx调大点。面试官如果调大之后过两天又 OOM 呢候选人A那就……继续调大面试官换了个候选人你呢你怎么查候选人B先看报的是哪种 OOM。Java heap space是堆、Metaspace是元空间、Direct buffer memory是直接内存这几种现场和排法完全不同。如果是堆先用jmapdump 下来丢进 MAT 看支配树找是谁在占内存同时用jstat -gcutil盯 GC 频率和曲线看是不是回收不动。查的时候心里要有个判断——是内存泄漏该回收的没回收还是内存本来就不够。前者要改代码找引用链后者才是调参数。面试官那你为什么先 dump 而不是先重启候选人B重启就没有现场了。现场比什么都值钱。今天这篇就是把这套排查流程完整走一遍。理论前面讲了三篇这篇全是手上有把螺丝刀怎么拆。一、先认清敌人OOM 长什么样几种OutOfMemoryError 有好几种报错信息里那句冒号后面的字直接决定了你往哪个方向查。最常见的几种-Java heap space——堆溢出。对象太多、内存泄漏、或者堆本来就不够。-Metaspace——元空间溢出JDK 8。类元数据太多典型是动态生成类。-PermGen space——永久代溢出JDK 7 及以前才有JDK 8 之后没了。-Direct buffer memory——直接内存溢出。NIO / Netty 场景的常客。-unable to create native thread——创建不了线程名字像栈其实是系统资源不够。-GC overhead limit exceeded——GC 干了太多活却没收获。默认当 GC 时间占比超过 98%、而回收出来的空间不足 2% 时抛出由-XX:GCTimeLimit、-XX:GCHeapFreeLimit控制。本质上是堆快满了但 GC 已经无能为力。还有一类不是 OutOfMemoryError但排查时老一起出现——StackOverflowError栈溢出一般发生在递归太深的时候。记住这张表能省你一半的瞎查时间。看到Direct buffer memory却去 dump 堆方向从一开始就错了。二、先分清内存泄漏还是内存不够这一步很多人跳过直接上手调-Xmx结果要么治标不治本要么白调。内存泄漏对象明明不该被引用了却因为某个引用链一直挂着GC 回收不掉。它的特征是——内存随时间一路往上涨老年代占用越来越高Full GC 越来越频繁但每次 GC 之后老年代的水位几乎不下降。这种你调多大堆都没用早晚撑爆必须改代码。内存本来就不够业务数据量确实大堆就是不够用。它的特征是——加了内存之后问题明显缓解甚至消失属于容量规划的范畴。怎么区分看两次 Full GC 之后老年代的水位。如果 Full GC 前 90%、Full GC 后还是 90%那就是泄漏——回收根本收不动。如果 Full GC 前 90%、Full GC 后掉到 40%那多半是容量不够或者流量突发。还有个更省事的办法启动时加上-XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/your/path。这样一旦 OOMJVM 自动把堆 dump 下来你连赶在重启前 dump这一手都省了。生产环境强烈建议默认带上。三、工具箱五个命令各管一段JDK 自带的那几个命令行工具排查 OOM 就靠它们。先把各自管什么记住。jps列出当前机器上的 Java 进程和 PID。排查第一步先定位进程号。jstat看 GC 统计。最常用的是# 每 1000ms 打印一次 GC 统计共打印 10 次 jstat -gcutil pid 1000 10输出里的列要能看懂S0、S1是两个 Survivor 区的使用率E是 EdenO是老年代M是元空间JDK 8 里是MJDK 7 是PYGC/FGC是年轻代、Full GC 的次数YGCT/FGCT/GCT是对应的耗时。你盯着一行行刷看O这个老年代使用率有没有持续上涨、FGC涨得快不快基本就能判断压力在哪。jmap堆的透视镜三个用法最重要jmap -heap pid # 看堆的配置和使用情况 jmap -histo:live pid | head -30 # 对象直方图哪类对象最多、最占内存 jmap -dump:live,formatb,fileheap.hprof pid # 把堆 dump 下来-histo输出的是类 → 实例数 → 占用字节的排行一眼能看出是不是某个类的实例多到离谱——比如几百万个UserDto那问题基本就在它身上。-dump输出的.hprof文件是给 MAT 分析用的。有个坑要记带live的-histo:live和-dump:live会先触发一次 Full GC再统计存活对象。这能过滤掉垃圾但也意味着——它会 STW对线上是有影响的。所以这两条命令在生产环境上要谨慎最好留到低峰期或者干脆用-XX:HeapDumpOnOutOfMemoryError在 OOM 那一刻自动 dump。jstack打印线程栈。jstack pid stack.txt它主要用来抓线程状态——死锁、线程卡在哪、某个线程栈有多深。排查创建不了线程和栈溢出的时候要用它。jinfo看运行时参数比如某次 JVM 到底带了哪些-XX。排查前先确认参数能避免很多我以为它是这么配的。想更顺手的话可以上Arthasdashboard一目了然、heapdump导堆、thread看线程或者VisualVM它们把上面这些命令包成了可视化界面。但底层原理就是这几个命令面试时说出命令名和参数比只说用工具看一下有说服力得多。四、堆溢出dump 下来丢进 MAT堆 OOM 是最高频的排查流程也最标准。第一步确认现场。用jstat -gcutil看老年代O是不是居高不下、Full GC 之后也不掉FGC是不是在短时间内猛涨。如果是基本坐实了堆的问题。第二步拿到 dump。要么用jmap -dump:live,formatb,fileheap.hprof pid手动抓要么靠-XX:HeapDumpOnOutOfMemoryError自动抓。第三步MAT 分析。MATEclipse Memory Analyzer是分析 hprof 的主力工具。打开 dump 之后重点看三个地方-Histogram直方图按类统计实例数和占用找出哪类对象最多。它和jmap -histo是一个意思但 MAT 里能展开看具体实例。-Dominator Tree支配树这是 MAT 最有价值的视图。它按如果我释放了 A能连带释放多少内存来排序也就是看谁真正占着大头。直方图告诉你哪个类多支配树告诉你谁真正霸占了内存——一个类实例多但如果它们都被别的东西引用着那真正的元凶是那个引用者。找内存泄漏看支配树比看直方图准得多。-Leak Suspects泄漏嫌疑MAT 的自动报告会先把最可疑的几个内存块圈出来给你省时间。第四步找引用链。锁定了可疑对象就对它做Path to GC Roots——看它到底是从哪个 GC Root 一路引用过来的。这一步是定位泄漏源头的关键。查的时候记得排除弱引用和软引用exclude weak/soft references因为软引用、弱引用本身不会阻止回收被它们挂着不算泄漏排除掉才能暴露出真正的强引用链。举个例子排查下来经常看到这样的链条某个对象被一个 static 的Map引用着这个 Map 只往里放、从来不清理——典型的缓存没设上限或者监听器注册了没注销。找到这条链问题就解决了一半。五、非堆的三种 OOM元空间、栈、直接内存剩下三种 OOM 不在堆上光 dump 堆是查不出来的得换个思路。元空间溢出Metaspace特征是jstat里M这一列一直涨、GC 也不掉。根源多半是动态生成类——CGLIB 代理、大量反射、字节码增强框架、热部署。查的方向是谁在不停造类可以配合jmap -clstats pid看已加载的类统计或者加-XX:TraceClassLoading把类加载过程打出来。解药通常是给元空间设上限-XX:MaxMetaspaceSize但这只是兜底真正的修复是找出那个无限造类的代码。栈溢出 / 线程创建失败StackOverflowError用jstack一看就知道——某个线程的栈深得离谱通常是递归没有终止条件。而unable to create native thread要看的是是不是线程数开太多线程池没设上限、或者每个请求 new 一个线程也可能是操作系统层面的线程数、句柄数限制。这时候jstack数一下线程数量、ulimit看一眼系统限制方向就有了。直接内存溢出Direct buffer memory最阴的一种。它的特征是——堆看起来很正常机器物理内存却在飙升。DirectByteBuffer对象在堆里很小真正的大内存在堆外。jstat看堆一切正常但进程的 RES 内存涨得吓人。查的方向确认-XX:MaxDirectMemorySize是怎么配的不显式配的话默认跟-Xmx挂钩检查是不是 NIO / Netty 用得多但DirectByteBuffer回收不及时。想让 JVM 把本地内存的去向打出来可以用-XX:NativeMemoryTrackingsummary再用jcmd pid VM.native_memory summary看。这种问题光看堆的 GC 日志会被骗过去。整张流程图捋下来就一句话先看错误类型定方向 → 用 jstat 看趋势判断是不是泄漏 → 该 dump 的 dump、该 jstack 的 jstack → 用 MAT / 引用链定位到具体代码 → 改代码参数只是兜底。 面试官真正想听的答案问他 OOM 排查他想听的不是加内存、重启也不是工具名背诵。他想知道你有没有一套能落地、有判断、有条理的方法。第一层给结论查 OOM 第一步是看错误类型定方向——Java heap space查堆、Metaspace查类加载、Direct buffer memory查堆外、unable to create native thread查线程数。第二步用jstat -gcutil看趋势判断是内存泄漏还是容量不够。第三步按区域选工具堆用jmapdump MAT 看支配树和引用链元空间和直接内存要另查。工具就那五个——jps、jstat、jmap、jstack、jinfo。第二层讲判断力能区分内存泄漏和内存不够是这条的分水岭。泄漏看Full GC 后老年代水位不降要改代码不够看加内存就缓解是容量规划。另外生产环境第一原则是先保现场再动手重启之前先把 dump 拿到——所以-XX:HeapDumpOnOutOfMemoryError应该默认开着。第三层用工具细节证明你真用过jmap -dump:live会先触发一次 Full GC、有 STW 影响所以线上要谨慎MAT 里看支配树比看直方图准因为支配树才是真正占内存的那个找引用链时要排除软引用和弱引用直接内存 OOM 的特点是堆正常、机器内存爆得用 NativeMemoryTracking 才看得见。能把这些细节讲出来面试官就知道你是真的排过线上问题而不是背了篇文章。下篇预告OOM 排查讲完了下一篇聊 JVM 调优——参数到底怎么配。堆开多大、新生代老年代怎么分、-Xms和-Xmx该不该设成一样、GC 日志怎么看、延迟敏感和吞吐敏感的服务该怎么选收集器和参数。到时候会把一套从零配置一个服务 JVM的思路走一遍先定堆大小再选收集器再调停顿目标再用 GC 日志验证。不讲玄学参数只讲每个参数在解决什么问题。想预习的话把-Xms -Xmx -Xmn -Xss -XX:MetaspaceSize -XX:MaxMetaspaceSize -XX:SurvivorRatio这几个先过一眼。唠点键盘之外的 · 第 26 篇

相关新闻

叮当小宝CS话术库:尺码不合适要换货?换货运费承担的话术边界

叮当小宝CS话术库:尺码不合适要换货?换货运费承担的话术边界

尺码不合适,换货可以,运费谁出?这个问题没有统一答案,答案取决于原因归谁。客服如果答错方向,要么店铺白掏一笔运费,要么买家觉得被推诿,两边都是成本。把归因判断前置,再谈运费&…

2026/10/13 6:55:54 阅读更多 →
Inno Setup 安装界面美化:从基础换图到高DPI自适应UI改造

Inno Setup 安装界面美化:从基础换图到高DPI自适应UI改造

简介:本资源是一套面向Windows桌面软件开发者与UI设计师的InnoSetup安装/卸载界面美化实战方案,聚焦nwjs等Electron类应用的安装体验升级,解决默认安装向导风格单一、品牌感弱、用户第一印象差等实际问题。压缩包含183个文件,主体…

2026/10/13 6:54:53 阅读更多 →
开源Personal Agent落地实战:架构设计与部署避坑指南

开源Personal Agent落地实战:架构设计与部署避坑指南

1. 从爆火概念到开源落地:Personal Agent 到底在解决什么问题Personal Agent 这个词最近几个月在技术社区里被反复提起,几乎每隔几天就能看到有人在讨论某个新产品又刷新了演示效果。简单来说,Personal Agent 就是一个能替你操作电脑、浏览器…

2026/10/13 6:54:53 阅读更多 →

最新新闻

游戏出海新路径:经销商合作计划如何破解本地支付与销售难题

游戏出海新路径:经销商合作计划如何破解本地支付与销售难题

1. 项目概述:游戏出海,为什么靠经销商打开本地市场反而更靠谱?做游戏出海的这两年,我越来越意识到一个容易被忽略的真相:渠道的本地化,往往比内容的本地化更难,也更重要。很多开发者以为把游戏文…

2026/10/13 8:17:34 阅读更多 →
长尾关键词挖掘与内容布局:网站SEO流量稳步提升的核心策略

长尾关键词挖掘与内容布局:网站SEO流量稳步提升的核心策略

做SEO时间长了,你对“词”的态度会慢慢变化。刚入行时总盯着行业大词,整天想的是哪天真把一个高搜索量词做到首页就好。后来做过几个不同行业的站点,反而越来越踏实地在做一件事:把长尾关键词的挖掘和内容布局当日常。真正让一个网…

2026/10/13 8:17:34 阅读更多 →
WebGL Fundamentals:二维图形缩放(2D Scale)实战详解

WebGL Fundamentals:二维图形缩放(2D Scale)实战详解

图形学 【免费下载链接】webgl-fundamentals WebGL lessons that start with the basics 项目地址: https://gitcode.com/gh_mirrors/we/webgl-fundamentals 点击查看 免费下载 本教程出自 webgl-fundamentals 开源仓库的 WebGL 基础系列(日语版见 webg…

2026/10/13 8:17:34 阅读更多 →
COMSOL多物理场耦合实现三维材料损伤模拟

COMSOL多物理场耦合实现三维材料损伤模拟

1. 项目背景与核心价值在工程仿真领域,材料损伤模拟一直是极具挑战性的课题。传统有限元软件往往只能实现简单的线性损伤模型,而COMSOL Multiphysics凭借其强大的多物理场耦合能力和用户自定义功能,为复杂损伤行为的精确模拟提供了可能。这个…

2026/10/13 8:17:34 阅读更多 →
城市通勤轮胎选择指南:性能平衡与安全考量

城市通勤轮胎选择指南:性能平衡与安全考量

1. 城市通勤轮胎选择的核心考量城市道路环境对轮胎的考验远比我们想象中复杂。柏油路面、水泥接缝、减速带、井盖、施工路段碎石......这些日常通勤中频繁遇到的路况,都在无声地考验着轮胎的性能边界。作为每天与地面直接接触的部件,轮胎的选择直接关系到…

2026/10/13 8:17:34 阅读更多 →
Schema标记实战:用结构化数据占据整个SERP

Schema标记实战:用结构化数据占据整个SERP

1. "占据整个SERP"到底是怎么回事:从一次搜索结果截图说起先别急着上代码,我们得先搞清楚一个问题:所谓"占据整个SERP",到底长什么样?去年我接手了一个垂直电商的小项目,卖的是某种小众…

2026/10/13 8:16:34 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →