前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库Docker 内存限制 OOM killed cgroup
DoDocker容器运行

Docker 的 -m/--memory 限制超出时容器进程会发生什么,如何验证?

容器内存超限可能触发cgroup OOM killer,若主进程被杀则容器退出并返回137;可用docker inspect查看State.OOMKilled是否为true。

前端进阶之旅 · 一题精讲更新于 2026.09.05
Docker#容器运行#Agent 记忆#容器化#并发编程
先看核心答案
理解线索

cgroup内存上限与OOM触发

  1. 内存记账cgroup统计匿名页+文件页,超出限制且无法回收时触发OOM。
  2. OOM选择基于oom_score选择cgroup内一个进程杀掉。
  3. 退出码被SIGKILL的进程通常造成退出码137。

只有设置-m并达到内存上限才触发,不设置则依赖宿主机全局OOM。

核心回答

先记住这个答案

当容器内所有进程的内存使用总量超过-m限制时,内核内存cgroup控制器触发OOM killer,选取一个进程发送SIGKILL以回收内存。若被杀进程是容器主进程,容器退出并返回137。验证方法包括:docker inspect查看State.OOMKilled为true且ExitCode为137,或在宿主机运行dmesg查看内核日志中的oom-killer记录。注意容器可能不退出如果主进程存活,但一般会优先杀死占用内存最高的进程。

  • 内存超限触发cgroup OOM killer,主进程被杀则退出137。
  • 用docker inspect的OOMKilled字段确认。
  • 内核日志中可查cgroup OOM记录。

cgroup内存上限与OOM killer触发机制

进程申请内存时,内核的memory cgroup会检查当前cgroup已用内存加上新申请是否超出limit_in_bytes。若超出且无法通过回收足够内存,内核会触发OOM事件,实质是调用out_of_memory()并遍历该cgroup的所有进程,选择oom_score最高的进程执行SIGKILL。Docker的-m直接设置cgroup v1的memory.limit_in_bytes或v2的memory.max。

OOM killer选择进程时会参考进程的oom_score_adj,默认Docker不调整容器内进程的该值,因此消耗内存最多的进程通常先被杀。被杀进程收到SIGKILL后直接终止,如果该进程恰好是PID 1(主进程),容器就会停止并返回128+9=137的退出码。如果被杀的只是子进程,容器可能还活着,但可能处于异常状态。

Java内存容器被OOM的实际场景

假设一个Java服务在容器内运行,启动参数-Xmx512m,但容器只设置了-m=512m。JVM默认堆外内存可能占用200MB,导致总内存很快逼近512MB。当JVM尝试分配新对象时,cgroup检测到超限,OOM killer选中JVM进程并杀之,容器随即退出,docker inspect显示OOMKilled: true和ExitCode: 137。

为避免此问题,应综合计算JVM堆与堆外内存,设置-m=1g等更合理值。也可使用--oom-kill-disable但必须与-m同时设置,否则宿主机危险。此时超限不会杀进程,但会导致不必要的系统和Swap压力,因此生产环境更建议调整应用与限制。

限制边界与验证陷阱

cgroup OOM只影响该容器,不会直接波及宿主机其他进程;但宿主全局内存耗尽会触发系统级OOM,可能杀死Docker daemon。此外-m限制包含文件缓存,当容器大量读文件导致page cache增长时也可能触发OOM,即使匿名内存不高。这种场景属于内核需要回收内存却无法及时压缩,容易误判。

验证时注意docker inspect的OOMKilled字段仅在当前容器运行期有效,如果容器自动重启(如--restart=always)则状态被重置,应依赖内核日志,例如dmesg中出现“Memory cgroup out of memory: Killed process”字样,是可靠依据。

回答前,多想一步

容易答错的地方

认为容器内所有进程都会被杀死
错误。OOM killer只选一个进程,通常是最耗内存的。如果主进程恰好不是最高分,容器可能继续运行,但功能可能受损。实际多数场景主进程就是最大占用者。
认为docker stats内存达标就立即OOM
错误。docker stats以1秒间隔采集,可能滞后;且触发OOM需要内核在申请内存时判定,存在瞬时性。正确验证依赖OOMKilled字段和内核日志。
试着用自己的话回答

面试官还会怎么问?

如何调整容器内进程被OOM killer选中的优先级?

可用--oom-score-adj调整整容器的OOM分数偏移,或对容器内进程调/proc/pid/oom_score_adj。但官方不推荐设置极端负值,以免系统无法保护关键进程。

`--oom-kill-disable`有什么使用前提?

必须与-m同时使用,否则当宿主内存不足时内核可能尝试杀宿主机进程。启用后容器超限不会被杀,但可能导致系统内存压力持续和swap浪费,官方对此有警告。

如何区分cgroup OOM与宿主机系统级OOM?

查看内核日志:cgroup OOM包含“Memory cgroup out of memory”,系统OOM包含“Out of memory: Kill process”。容器没有独立内核,日志在宿主机。

从一道题,走向一组知识

把知识连起来

容器运行

Docker 的 --cpu-shares 与 --cpus(CFS quota)在 CPU 争抢与空闲时行为有何不同?

同属「容器运行」专题,接着看 Docker CPU 限制 cpu-shares cpus 区别 在具体场景中的处理方式。

容器运行

为什么 Docker 容器内的主进程 PID 是 1,这会带来什么问题?

同属「容器运行」专题,接着看 Docker 容器 PID 1 进程 问题 在具体场景中的处理方式。

参考资料

  • Resource constraints

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. cgroup内存上限与OOM killer触发机制
  3. Java内存容器被OOM的实际场景
  4. 限制边界与验证陷阱
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑