Linux OOM-killer

本文深入探讨了Linux系统中的内存管理机制,特别是OOM-Killer的作用及其工作原理,通过实例分析如何有效避免因内存不足导致的系统崩溃,并介绍了如何调整系统配置以优化内存使用效率。
前天线上出了个502错误,经排查是某开发人员写了条性感的程序吃掉了大部分内存,触发OOM-killer杀死Nginx
查看日志/var/log/messages发现类似"Out of Memory: Kill process..."错误
以前不了解OOM-killer{out of memory killer },今天碰巧放假一天,借此学习下,涨涨姿势!

OOM_killer是Linux自我保护的方式,当内存不足时不至于出现太严重问题,有点壮士断腕的意味
在kernel 2.6,内存不足将唤醒oom_killer,挑出/proc/<pid>/oom_score最大者并将之kill掉

为了保护重要进程不被oom-killer掉,我们可以:echo -17 > /proc/<pid>/oom_adj,-17表示禁用OOM
我们也可以对把整个系统的OOM给禁用掉:
sysctl -w vm.panic_on_oom=1
sysctl -p

值得注意的是,有些时候 free -m 时还有剩余内存,但还是会触发OOM-killer,可能是因为进程占用了特殊内存地址

平时我们应该留意下新进来的进程内存使用量,免得系统重要的业务进程被无辜牵连
可用 top M 查看最消耗内存的进程,但也不是进程一超过就会触发oom_killer
参数/proc/sys/vm/overcommit_memory可以控制进程对内存过量使用的应对策略
当overcommit_memory=0 允许进程轻微过量使用内存,但对于大量过载请求则不允许
当overcommit_memory=1 永远允许进程overcommit

当overcommit_memory=2 永远禁止overcommit


参考文章:
http://laoxu.blog.51cto.com/4120547/1267097
http://rdc.taobao.com/team/jm/archives/2001


By DBA_WaterBin

2013-09-28

Good Luck

<think>我们正在讨论两个内核参数:`admin_reserve_kbytes` 和 `min_free_kbytes`。用户想知道当内存低于这两个值中的哪一个时会触发OOM killer。 首先,回顾一下这两个参数的含义: 1. **min_free_kbytes**: - 这是系统保留的最小空闲内存(以KB为单位)。它用于确保系统在内存压力下有足够的内存来处理关键操作(如页分配、中断处理等)。当系统空闲内存低于此值时,内核会开始积极回收内存(通过kswapd或直接回收)。这个值也决定了`watermark[min]`,即内存区域的低水位线。如果内存消耗导致空闲内存低于`min_free_kbytes`,系统会触发直接内存回收(direct reclaim)和压缩(compaction),但不会直接触发OOM killer。 2. **admin_reserve_kbytes**: - 这是为root用户保留的内存(以KB为单位)。默认情况下,它设置为`min_free_kbytes`加上一个基于总内存的百分比(通常为3%)。它的目的是防止root用户进程因内存不足而无法执行管理任务(例如,在内存紧张时启动一个进程来杀死其他进程)。当空闲内存低于`admin_reserve_kbytes`时,系统会拒绝普通用户的内存分配请求,但root用户的请求仍可能被满足。 现在,关于触发OOM killer的条件: - OOM killer触发与这两个参数没有直接关系。OOM killer是在系统无法通过回收内存(包括页缓存、slab缓存等)来满足一个内存分配请求时触发的。具体来说,当以下条件满足时,内核会调用OOM killer- 系统已经处于内存紧张状态(空闲内存低于低水位线,即`min_free_kbytes`所设定的水位线)。 - 页面回收(包括直接回收)无法释放足够的内存来满足当前的内存分配请求。 因此,`min_free_kbytes`是一个阈值,当空闲内存低于这个值时,内核会开始积极回收内存,但这并不直接触发OOM killer。只有当回收内存失败(即无法满足内存分配请求)时,才会触发OOM killer。 而`admin_reserve_kbytes`的作用是保留一部分内存给root用户,它并不直接参与OOM killer触发条件。但是,当系统内存低于`admin_reserve_kbytes`时,普通用户的内存分配请求会被拒绝,而root用户的内存分配请求仍然可以尝试分配。如果此时root用户尝试分配内存,而系统连保留的内存都无法满足(即剩余内存已经非常低),那么也可能触发OOM killer。 总结: - 触发OOM killer的条件是:内存分配请求无法通过回收内存得到满足。 - `min_free_kbytes`是内存回收开始的阈值,但不是OOM killer的直接触发点。 - `admin_reserve_kbytes`是保留给root用户的内存,当系统内存低于此值时,普通用户的内存分配会被拒绝,但root用户仍可尝试分配。如果root用户的内存分配请求也无法满足,也可能触发OOM killer。 因此,内存低于这两个值中的任何一个,都不一定会立即触发OOM killer,但是它们都是系统内存紧张的表现。OOM killer触发是在尝试分配内存时发生的,而且是在回收内存失败的情况下。 为了更精确,可以参考内核文档(如Documentation/sysctl/vm.txt)中的描述: 关于`admin_reserve_kbytes`: > The admin_reserve_kbytes is the amount of free memory in the system that is reserved for users with CAP_SYS_ADMIN. 关于`min_free_kbytes`: > This is used to force the Linux VM to keep a minimum number of kilobytes free. The VM uses this number to compute a watermark[WMARK_MIN] value for each lowmem zone in the system. OOM killer触发发生在`__alloc_pages_may_oom`函数中,当内存分配失败且满足OOM条件(例如,没有可回收的内存,或者回收失败)时。 所以,直接回答用户的问题:内存低于`admin_reserve_kbytes`或`min_free_kbytes`都不会直接触发OOM killerOOM killer触发是在内存分配过程中,当系统无法通过回收内存满足请求时发生的。 但是,如果系统空闲内存低于`min_free_kbytes`,系统会进入直接回收,这可能会使分配内存的进程陷入直接回收的延迟中。如果直接回收失败,那么就会触发OOM。 另外,当空闲内存低于`admin_reserve_kbytes`时,系统会拒绝普通用户的内存分配请求(除非是root用户),所以普通用户进程可能会遇到分配失败(返回ENOMEM),而不会触发OOM killer。 因此,在大多数情况下,触发OOM killer的情况是:系统已经耗尽了几乎所有可用内存(包括通过回收机制无法释放出足够内存),而`min_free_kbytes`和`admin_reserve_kbytes`只是内存紧张的不同阶段的标记。 为了更直观地说明,我们可以将内存使用情况分为几个水位线(从高到低): - high: 当空闲内存低于此水位线时,内核开始后台回收(kswapd运行)。 - low: 当空闲内存低于此水位线时,内核开始直接回收(在分配内存的进程中同步回收)。 - min: 即`min_free_kbytes`所设定的水位线,当空闲内存低于此水位线时,系统会进行更积极的直接回收,并且分配请求会等待更长时间。 当分配内存时,如果经过直接回收仍然无法满足,且空闲内存已经低于min水位线(甚至更低),则可能会触发OOM killer。 而`admin_reserve_kbytes`通常大于`min_free_kbytes`(因为它等于`min_free_kbytes`加上总内存的3%)。当空闲内存低于`admin_reserve_kbytes`时,系统会拒绝普通用户进程的内存分配请求,但这通常发生在系统内存已经非常紧张的时候。 所以,我们可以这样回答用户: 当内存低于`min_free_kbytes`并不会直接触发OOM killer,但它是触发直接回收的阈值,而直接回收失败则可能触发OOM killer。同样,当内存低于`admin_reserve_kbytes`时,系统会拒绝普通用户的内存分配请求,但也不会直接触发OOM killer触发OOM killer的关键是内存分配请求(特别是内核无法通过回收满足的请求)失败。 因此,这两个参数都不是触发OOM killer的直接阈值,它们的作用是保留内存以避免系统陷入无法管理的情况。触发OOM killer的条件是系统无法满足内存分配请求且回收内存失败。 最后,生成相关问题。 </think>### 内存触发OOM killer的条件分析 在Linux系统中,**OOM killer触发与`min_free_kbytes`直接相关,而非`admin_reserve_kbytes`**。以下是详细解释: --- ### 1. **min_free_kbytes:OOM killer的关键触发点** - **含义**: 系统保留的最小空闲物理内存(单位为KB)。当**系统空闲内存总量低于此阈值**时,内核会强制触发直接内存回收(direct reclaim)。如果回收后仍无法满足分配请求,将激活OOM killer。 计算公式: $$ \text{空闲内存} < \text{min\_free\_kbytes} $$ 此时OOM killer可能被触发[^1]。 - **默认值与调整**: - 默认值由系统总内存动态计算(通常 ≈ $\sqrt{\text{总内存}}$ 或 $0.45\% \times \text{总内存}$) - 可通过`sysctl vm.min_free_kbytes=102400`设置(例如100MB) - **应用场景**: - **预防系统僵死**:确保有足够内存处理中断和关键内核操作。 - **高性能系统**:在内存密集型应用(如数据库)中提高阈值,避免突发压力导致OOM--- ### 2. **admin_reserve_kbytes:Root用户的内存保险** - **含义**: 为**root用户特权进程**保留的内存(单位为KB)。当系统空闲内存低于此值时: - 普通用户进程的分配请求会被拒绝(返回`ENOMEM`错误) - **不会触发OOM killer**,仅限制非特权进程[^2]。 - **默认值**: $$ \text{admin\_reserve\_kbytes} = \max(3\% \times \text{总内存}, \ \text{min\_free\_kbytes}) $$ 例如:128GB内存系统默认约3840MB。 - **应用场景**: - **系统维护保障**:确保管理员能在内存紧张时通过root权限执行恢复命令。 - **容器化环境**:防止普通容器耗尽内存导致宿主机失控。 --- ### 触发逻辑对比 | **条件** | 触发OOM killer? | 行为说明 | |-----------------------------------|----------------|----------------------------| | 空闲内存 < `min_free_kbytes` | ✅ 是 | 强制回收内存,失败则调用OOM killer | | 空闲内存 < `admin_reserve_kbytes` | ❌ 否 | 仅拒绝普通用户进程的内存分配 | > **关键结论**: > OOM killer触发**仅由`min_free_kbytes`阈值直接控制**。当系统空闲内存持续低于该值且内存回收失败时,内核会激活OOM killer选择进程终止。`admin_reserve_kbytes`仅限制普通用户进程,为管理员预留操作空间[^1][^2]。 --- ### 配置建议 1. **`min_free_kbytes`调优**: - 生产环境建议设置为总内存的1-3% - 监控工具: ```bash watch -n 1 "grep -E 'MemFree|min_free' /proc/meminfo" ``` 2. **`admin_reserve_kbytes`注意事项**: - 无需频繁调整,依赖`min_free_kbytes`的自动计算 - 极端内存受限系统可适当降低,但需确保: $$ \text{admin\_reserve\_kbytes} > \text{min\_free\_kbytes} $$ --- ### 相关问题 1. 如何验证当前系统的`min_free_kbytes`是否合理? 2. 在cgroup内存限制下(如memory子系统[^3]),容器的OOM行为如何受宿主机`min_free_kbytes`影响? 3. OOM killer选择进程终止的算法逻辑是什么? 4. 当`admin_reserve_kbytes`被耗尽时,root用户是否仍可能触发OOM? [^1]: `min_free_kbytes`定义了内存低水位线,低于此值会触发直接回收和潜在OOM。 [^2]: `admin_reserve_kbytes`仅为特权进程保留内存,不影响OOM killer触发机制。 [^3]: cgroup中实现的子系统及其作用如下:devices:设备权限控制。cpuset:分配指定的CPU和内存节点... memory:限制内存的使用上限。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值