container@进程oom分析
问题
容器运行一段时间发现有重启过,为什么重启找下原因?
env
- centos7.8
- docker
日志
如下一段 dmesg -T
的内核日志,显示了 Docker 容器因内存限制被 OOM 杀手(Out Of Memory Killer)终止 的过程。
[Wed May 28 23:55:16 2025] Hardware name: Alibaba Cloud Alibaba Cloud ECS, BIOS 2221b89 04/01/2014
[Wed May 28 23:55:16 2025] Call Trace:
[Wed May 28 23:55:16 2025] [<ffffffff99fb1bec>] dump_stack+0x19/0x1f
[Wed May 28 23:55:16 2025] [<ffffffff99facb4f>] dump_header+0x90/0x22d
[Wed May 28 23:55:16 2025] [<ffffffff99fba710>] ? _raw_spin_trylock+0x50/0x50
[Wed May 28 23:55:16 2025] [<ffffffff999cce16>] ? find_lock_task_mm+0x56/0xd0
[Wed May 28 23:55:16 2025] [<ffffffff99a4a458>] ? try_get_mem_cgroup_from_mm+0x28/0x70
[Wed May 28 23:55:16 2025] [<ffffffff999cd3a5>] oom_kill_process+0x2d5/0x4a0
[Wed May 28 23:55:16 2025] [<ffffffff99a4e93c>] mem_cgroup_oom_synchronize+0x55c/0x590
[Wed May 28 23:55:16 2025] [<ffffffff99a4dd90>] ? mem_cgroup_charge_common+0xc0/0xc0
[Wed May 28 23:55:16 2025] [<ffffffff999cdca4>] pagefault_out_of_memory+0x14/0x90
[Wed May 28 23:55:16 2025] [<ffffffff99faaf88>] mm_fault_error+0x6a/0x15b
[Wed May 28 23:55:16 2025] [<ffffffff99fbfa61>] __do_page_fault+0x4a1/0x510
[Wed May 28 23:55:16 2025] [<ffffffff99fbfbb6>] trace_do_page_fault+0x56/0x150
[Wed May 28 23:55:16 2025] [<ffffffff99fbf112>] do_async_page_fault+0x22/0x100
[Wed May 28 23:55:16 2025] [<ffffffff99fbb7e8>] async_page_fault+0x28/0x30
[Wed May 28 23:55:16 2025] Task in /docker/78d543660f71a779c906e792664dd8fb1910e0a108a8974f46bf68f4a1e85de9 killed as a result of limit of /docker/78d543660f71a779c906e792664dd8fb1910e0a108a8974f46bf68f4a1e85de9
[Wed May 28 23:55:16 2025] memory: usage 6291456kB, limit 6291456kB, failcnt 1109137
[Wed May 28 23:55:16 2025] memory+swap: usage 6291456kB, limit 12582912kB, failcnt 0
[Wed May 28 23:55:16 2025] kmem: usage 0kB, limit 9007199254740988kB, failcnt 0
[Wed May 28 23:55:16 2025] Memory cgroup stats for /docker/78d543660f71a779c906e792664dd8fb1910e0a108a8974f46bf68f4a1e85de9: cache:1020KB rss:6290436KB rss_huge:0KB mapped_file:4KB swap:0KB inactive_anon:4KB active_anon:6290436KB inactive_file:580KB active_file:408KB unevictable:0KB
[Wed May 28 23:55:16 2025] [ pid ] uid tgid total_vm rss nr_ptes swapents oom_score_adj name
[Wed May 28 23:55:16 2025] [ 8682] 0 8682 1082 394 7 0 0 bash
[Wed May 28 23:55:16 2025] [ 8714] 0 8714 4072191 1569923 4137 0 0 python
[Wed May 28 23:55:16 2025] Memory cgroup out of memory: Kill process 10599 (python) score 1000 or sacrifice child
[Wed May 28 23:55:16 2025] Killed process 8714 (python), UID 0, total-vm:16288764kB, anon-rss:6271900kB, file-rss:7988kB, shmem-rss:4kB
💥 整体结论:
容器 /docker/78d543...
中的一个 python
进程占用了大量内存,超出了限制(6GB),触发了 OOM 杀手机制,最终被系统强制终止。
限制一方面是docker-compose limit or system memory limit
📜 日志逐行解析:
关键系统信息:
[Wed May 28 23:55:16 2025] Hardware name: Alibaba Cloud Alibaba Cloud ECS, BIOS 2221b89 04/01/2014
这台机器是运行在阿里云上的虚拟机(ECS)。
调用栈(Call Trace):
Call Trace:
[<...>] dump_stack
[<...>] dump_header
...
这些是内核触发 OOM 时输出的调用堆栈信息,供开发者排查,正常用户可略过。
容器内存超限:
Task in /docker/78d543660f71... killed as a result of limit of /docker/78d543660f71...
这说明某个容器的进程因为超过内存限制被终止。
内存使用情况:
memory: usage 6291456kB, limit 6291456kB, failcnt 1109137
usage
: 当前使用内存是 6GB(6291456KB)limit
: 容器设置的内存上限也是 6GBfailcnt
: 有 1109137 次尝试使用内存失败(已达上限)
memory+swap: usage 6291456kB, limit 12582912kB
- 启用了 swap,总限制为 12GB,但实际 swap 并没有用上(见下)。
swap:0KB
被杀进程前的状态:
[ 8714] 0 8714 4072191 1569923 ...
这个 python
进程(PID 8714):
total_vm
: 虚拟内存空间大约是 16GB(4072191 页 * 4KB)rss
: 实际驻留内存是 ~6GB(1569923 页)
杀进程:
Memory cgroup out of memory: Kill process 10599 (python) score 1000 or sacrifice child
Killed process 8714 (python), UID 0, total-vm:16288764kB, anon-rss:6271900kB
- OOM Killer 选择了
python
进程(PID 8714)进行终止 - 原因是其
oom_score
高达 1000(最高优先级被杀) - 实际占用了约 6GB 匿名页内存
🛠 建议与解决方案:
1. 增加容器内存限制
如果进程是正常业务逻辑(如训练模型、处理大数据),建议将容器内存限制调大:
1 | docker run -m 8g ... |
或在 Docker Compose / Kubernetes 配置中设置更高的内存限制。
2. 优化 Python 应用内存占用
- 检查是否有内存泄漏(使用
tracemalloc
,objgraph
等工具) - 分批处理数据,避免一次加载过多数据
- 释放不再使用的对象,强制
gc.collect()
(如果合理)
3. 使用 cgroups
或 systemd
分析/监控
也可以用 systemd-cgtop
或 cat /sys/fs/cgroup/...
跟踪各个 cgroup 的内存使用情况。