oom-killer

本文深入探讨了Linux系统在内存资源紧张时如何触发oom-killer机制,详细解析了其工作原理、内核代码位置、以及如何通过配置/调整参数避免不必要的进程被kill。包括oom-killer如何选择并kill占用内存较高的进程,以及如何通过配置/调整进程的oom_adj和oom_score_adj来影响被kill的风险。

内存不够时系统会启动oom-killer
~ # xxx_test 192.168.1.29 192.168.1.71
rtl8168: eth0: link up
info [create_socket_srv:354]: listening on port : 6789
info [listen_func:304]: connection[4] : 192.168.1.71:43786
[process_cmd:365]: $taes #cd
ft2_test invoked oom-killer: gfp_mask=0x200da, order=0, oom_score_adj=0
CPU: 0 PID: 107 Comm: ft2_test Not tainted 3.10.27+ #401
Stack : 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 8efc9b98

Call Trace:[<800144f4>] 0x800144f4
[<800144f4>] 0x800144f4
[<80446c20>] 0x80446c20
[<80189f04>] 0x80189f04
[<80066744>] 0x80066744
[<80028420>] 0x80028420
[<800665e8>] 0x800665e8
[<80066568>] 0x80066568
[<80066ff0>] 0x80066ff0
[<8006a648>] 0x8006a648
[<8018ed24>] 0x8018ed24
[<8007ba94>] 0x8007ba94
[<8007e370>] 0x8007e370
[<8007e040>] 0x8007e040
[<800804a8>] 0x800804a8
[<8007bc88>] 0x8007bc88
[<80017428>] 0x80017428
[<800809c4>] 0x800809c4
[<8018add4>] 0x8018add4
[<80073cdc>] 0x80073cdc
[<8007f76c>] 0x8007f76c
[<8018add4>] 0x8018add4
[<8007eeac>] 0x8007eeac
[<80011ba4>] 0x80011ba4
[<8018eb98>] 0x8018eb98

Mem-Info:
Normal per-cpu:
CPU 0: hi: 90, btch: 15 usd: 33
active_anon:42496 inactive_anon:0 isolated_anon:0
active_file:0 inactive_file:2 isolated_file:0
unevictable:958 dirty:0 writeback:0 unstable:0
free:427 slab_reclaimable:163 slab_unreclaimable:343
mapped:156 shmem:0 pagetables:54 bounce:0
free_cma:0
Normal free:1708kB min:1728kB low:2160kB high:2592kB active_anon:169984kB inactive_anon:0kB active_file:0kB inactive_file:8kB unevictable:3832kB isolated(anon):0kB isolated(file):0kB present:262144kB managed:187256kB mlocked:0kB dirty:0kB writeback:0kB mapped:624kB shmem:0kB slab_reclaimable:652kB slab_unreclaimable:1372kB kernel_stack:272kB pagetables:216kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:46 all_unreclaimable? yes
lowmem_reserve[]: 0 0
Normal: 1*4kB (M) 1*8kB (U) 2*16kB (UM) 0*32kB 2*64kB (UM) 0*128kB 0*256kB 1*512kB (M) 1*1024kB (M) 0*2048kB 0*4096kB = 1708kB
960 total pagecache pages
65536 pages RAM
18347 pages reserved
270083 pages shared
44021 pages non-shared
[ pid ] uid tgid total_vm rss nr_ptes swapents oom_score_adj name
[ 84] 0 84 214 96 3 0 0 sh
[ 96] 0 96 46273 42577 48 0 0 ft2_test
Out of memory: Kill process 96 (ft2_test) score 873 or sacrifice child
Killed process 96 (ft2_test) total-vm:185092kB, anon-rss:169872kB, file-rss:436kB
Killed

oom-killer
oom-killer相关的内核代码位置在mm/oom-kill.c
oom-killer会在内存紧张的时候,依次kill内存占用较高的进程,发送signal 15(SIGTERM),并在/var/log/message中进行记录。

Oom-kill杀死进程的机制
/proc/vm/oom_adj 表示该pid进程被oom killer杀掉的权重,在[-17, 15]之间,越高的权重,意味着越有可能被oom-killer选中,-17表示禁止被kill掉。
/proc/vm/oom_score 当前进程被kill的分数,越高的分数,意味着越有可能被kill

<think>嗯,用户遇到了一个系统提示:“Monitor invoked oom-killer: gfp_mask=0x7080c0(GFP_KERNEL_ACCOUNT|__GFP_ZERO), nodemask=(null), order=1, oom_score_adj=0”,需要解释这个错误信息。首先,我要理解这个日志的含义。 首先,oom-killer是Linux内核在内存不足时触发的机制,用于终止进程以释放内存。用户看到的这条信息是系统在内存严重不足时,oom-killer被调用的记录。接下来需要拆解各个参数的意义。 gfp_mask=0x7080c0,这部分是内存分配标志的组合。GFP_KERNEL_ACCOUNT表示内核为某个进程分配内存并进行统计,可能用于cgroup等记账机制。__GFP_ZERO表示分配的内存会被初始化为零。组合起来,这次内存请求可能需要内核账户统计,并且需要清零的内存区域。 nodemask=(null)说明没有指定特定的NUMA节点,可以在所有节点分配内存。order=1表示请求分配2^1=2个连续的内存页,即8KB(假设页大小为4KB)。oom_score_adj=0说明触发oom-killer的进程的调整值为0,通常这个值越低,进程越不容易被杀死,但这里可能因为系统整体内存不足,即使调整值为0的进程也可能被终止。 接下来需要分析可能的原因。系统物理内存不足,或者存在内存泄漏导致内存耗尽。另外,虽然order=1看起来不大,但连续内存分配失败可能也是问题。还有cgroup的内存限制可能导致即使系统有空闲内存,特定cgroup中的进程也无法分配。 解决方案方面,需要检查内存使用情况,可以用free -h或top命令。检查内核日志dmesg获取更多OOM相关信息,找到被终止的进程。调整oom_score_adj可能预防问题,但需谨慎。增加系统内存或优化应用程序的内存使用也是根本方法。检查cgroup配置,确保没有不合理的内存限制。 用户可能需要具体的命令和步骤,比如如何查看内存,如何分析日志,如何调整参数。需要确保回答清晰,步骤明确,帮助用户逐步排查问题。同时提醒用户注意数据备份,避免在OOM发生时数据丢失。</think>这个日志信息是 Linux 系统在内存耗尽时触发的 `oom-killer` 机制的记录。以下是逐层解析和应对建议: --- ### 一、关键信息拆解 1. **`Monitor invoked omm-killer`** - 表示系统检测到内存不足(Out Of Memory),触发内核的 `oom-killer` 机制,该机制会强制终止某些进程以释放内存。 2. **`gfp_mask=0x7080c0(GFP_KERNEL_ACCOUNT|__GFP_ZERO)`** - `gfp_mask` 是内存分配的标志位组合: - `GFP_KERNEL_ACCOUNT`: 内核为进程分配内存时需进行会计统计(常用于 cgroup 内存控制)。 - `__GFP_ZERO`: 分配的内存需初始化为零值。 - 此标志组合表示内核正在尝试为某个进程分配需记账且清零的内存区域。 3. **`nodemask=(null)`** - 未指定 NUMA 节点(即允许在所有内存节点分配内存)。 4. **`order=1`** - 请求分配 $2^{\text{order}}$ 个连续物理页(通常页大小为 4KB,即申请 $2^1 \times 4\text{KB} = 8\text{KB}$ 连续内存)。 5. **`oom_score_adj=0`** - 触发 OOM 的进程的优先级调整值为 0(范围 -1000~1000,值越低越不易被终止)。 --- ### 二、可能原因 1. **系统物理内存不足** - 应用程序或内核模块消耗过多内存。 - 内存泄漏(如内核驱动或用户态进程未释放内存)。 2. **连续内存分配失败** - 尽管 `order=1` 请求的内存较小,但内核无法找到足够的连续物理页。 3. **cgroup 内存限制** - 若进程受 cgroup 限制,即使系统整体内存充足,进程也可能因 cgroup 配额耗尽触发 OOM--- ### 三、排查与解决步骤 #### 1. 检查内存使用情况 ```bash # 查看整体内存状态 free -h # 监控进程内存占用 top -o %MEM ``` #### 2. 分析 OOM 日志 ```bash # 查看完整内核日志(关注 OOM 前后的记录) dmesg | grep -i "oom-killer" dmesg | grep -i "killed process" ``` #### 3. 定位问题进程 - 日志中会记录被终止的进程名和 PID,例如: `Killed process 1234 (your_process)` #### 4. 调整 OOM 优先级(谨慎操作) ```bash # 降低某进程被终止的概率(值越小越安全) echo -100 > /proc/<PID>/oom_score_adj ``` #### 5. 优化内存使用 - 升级物理内存。 - 优化应用程序代码(减少内存泄漏,限制缓存大小)。 - 调整内核参数(如 `vm.overcommit_memory`)。 #### 6. 检查 cgroup 限制 ```bash # 若使用容器(如 Docker),检查内存限制 docker inspect <container_id> | grep -i "memory" ``` --- ### 四、典型场景示例 - **场景 1**:数据库服务(如 MySQL)因未配置内存上限,导致占用所有内存。 **解决**:在配置文件中限制 `innodb_buffer_pool_size`。 - **场景 2**:内核驱动存在内存泄漏。 **解决**:更新驱动或通过 `vmstat -s` 监控内核内存使用。 --- 若需进一步分析,请提供完整的 `dmesg` 日志或应用程序内存配置细节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luckywang1103

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值