Linux系统运行过程中,有时候会在message中看到Out of memory,并kill某个进程的信息。这篇文章讲的就是OOM机制的原理以及其核心配置参数。
内核版本基于centos6使用的linux-2.6.32。
OOM(Out Of Memory)机制为Linux内核中一种自我保护机制,当系统分配不出内存时(触发条件)会触发这个机制,由系统在已有进程中挑选一个占用内存较多,回收内存收益最大的进程杀掉来释放内存。
Linux下允许程序申请比系统可用内存更多的内存(如malloc函数),这个特性叫Overcommit。这么做是出于优化系统的考虑,因为并不是所有的程序申请了内存就立刻使用,当使用的时候说不定系统已经回收了一些内存资源了。不过当需要真正使用内存资源而系统已经没有多余的内存资源可用时,OOM机制就被触发了。
Linux下有3种Overcommit策略,可以通过/proc/sys/vm/overcommit_memory配置,取0、1和2三个值,默认是0:
1. 取值0:启发式策略,比较多的内存申请可能会被拒绝,如当前内存2G,突然申请1T的内存(一般当系统启动selinux模块时有效,其他情况等同取值1);
2. 取值1:允许分配比当前内存资源多的内存;
3. 取值2:系统所能分配的内存资源不能超过swap+内存资源*系数(/proc/sys/vm/overcommit_ratio,默认50%,可调整)。如果资源已经用光,再有内存申请请求时,都会返回错误。
OOM-kill策略
OOM-killer策略就是说在发生OOM时,会选择一些进程来杀掉以释放一部分缓存资源。
Linux下每个进程都有一个OOM权重,在/proc/<pid>/oom_adj里面,取值是-17到+15(为-17此进程不会被杀掉),取值越高,越容易被杀掉。
最终OOM-Killer是通过/proc/<pid>/oom_score这个值来决定哪个进程被杀死。这个值是系统综合进程的内存消耗量、CPU时间(utime+stime)、存活时间(utime - start_time)和oom_adj计算出的,消耗内存越多oom_score值越高,存活时间越长值越低。另外,Linux在计算进程的内存消耗的时候,会将子进程所耗内存的一半算到父进程中(有兴趣的话可以查看内核代码mm/oom_kill.c:badness函数)。
总之,OOM-Killer策略是:损失最少的工作,释放最大的内存;同时不伤及无辜的用了很大内存的进程,并且杀掉的进程数尽量少。
OOM机制实现
内核在触发OOM机制时会调用到out_of_memory函数,此函数的调用顺序如下:
__alloc_pages
|-->__alloc_pages_nodemask
|--> __alloc_pages_slowpath
|--> __alloc_pages_may_oom
| --> out_of_memory
以上函数__alloc_pages_may_oom在调用之前会先判断oom_killer_disabled的值,如果有值,则不会触发OOM机制;
Bool型变量oom_killer_disabled定义在文件mm/page_alloc.c中,并没有提供外部接口更改此值,但是在内核中此值默认为0,表示打开OOM-kill。
Linux中内存都是以页的形式管理的,所以不管是怎么申请内存,都会调用alloc_page函数,最终调用到函数out_of_memory,触发OOM机制。
下面简要说明函数out_of_memory流程。
函数out_of_memory
1. 判断全局变量sysctl_panic_on_oom==2,成立则直接panic
2. 获取/proc/sys/vm/overcommit_memory中的配置的值:
a) 为2:直接将当前进程杀死;
b) 为0:判断sysctl_panic_on_oom是否有值,有值直接panic,否则调用__out_of_memory函数;
c) 为1:调用__out_of_memory函数,其流程如下:
以上流程中值得关注的地方有:
1. 变量sysctl_panic_on_oom,此值可以通过/proc/sys/vm/panic_on_oom设置,默认为0;
2. 变量sysctl_oom_kill_allocating_task,此值可以通过/proc/sys/vm/oom_kill_allocating_task设置,默认为0;
3. 当内存资源紧张,同时也没有可以杀死的进程时,系统会panic;
4. 杀死进程需要调用函数oom_kill_process,此函数核心步骤就是先杀死指定进程的子进程p->children,然后杀死指定进程p,具体杀死进程的函数为oom_kill_task。
下面简要说明函数oom_kill_task。
函数oom_kill_task
此函数流程如下:
以上流程中值得关注的地方有:
1. p->signal->oom_adj的值,此值可以通过/proc/<pid>/oom_adj设置;
2. 变量sysctl_would_have_oomkilled,此值可以通过/proc/sys/vm/would_have_oomkilled设置,默认为0。
总结
通过前面介绍,可以看到Linux中OOM机制是否会触发,与以下几个变量有关:
1. oom_killer_disabled:此值虽然没有提供外部接口更改,但是可以通过给内核打patch,增加一个外部接口,使此值可动态改变
2. sysctl_panic_on_oom:此值一般不建议设置,因为如果申请不到内存,系统就panic了;
3. sysctl_oom_kill_allocating_task:此值设置为1,类似给接口/proc/sys/vm/overcommit_memory设置值为2,被设置后,某个进程要申请内存失败时直接将该进程杀死;
4. sysctl_would_have_oomkilled:此值设置为1,也不会真正的去杀死进程
5. p->signal->oom_adj:此值可以通过接口/proc/<pid>/oom_adj设置值为-17,表示该进程不可被杀死。
OOM机制的几组测试
测试1 打开OOM机制(默认)
物理机器配置:2G内存,无swap分区
执行命令:20个depmod -a命令
结果:
1. 机器运行一段时间,可以看到/var/log/message中出现out of memory: kill process信息;
2. 当无进程可杀时,机器panic。
测试2 关闭OOM机制
通过给内核打patch,将oom_killer_disabled值设置为1,另外通过sys接口将sysctl_would_have_oomkilled值设置为1。
1. 有swap分区时
物理机器配置:2G内存,2G大小swap分区
执行命令:20个depmod -a命令
结果:
a) 机器运行一段时间,/var/log/message中不出现out of memory: kill process * 字样
b) free -m -s 1命令观察当前内存使用情况,可以发现内存使用完毕后,开始使用swap分区,当swap分区使用完后,系统会每隔一段时间释放出一段swap分区的空间,此时机器很卡。
2. 无swap分区时
物理机器配置:2G内存,无swap分区
执行命令:20个depmod -a命令
结果:
a) 机器运行一段时间,/var/log/message中不出现out of memory: kill process * 字样;
b) free -m -s 1命令观察当前内存使用情况,可以发现内存使用完毕后,机器很卡,无法操作 ,但是可以ping通。
测试结果分析
关闭OOM机制,虽然不会出现杀进程的现象,但是应用程序在申请内存资源时由于内存资源紧张导致申请不到资源,可能会出现一直循环申请内存,直到申请到为止,在未申请到内存资源之前,会一直占用某个CPU不放,导致机器卡住。
从测试中可以看到,swap分区能够缓解一下内存紧张的情况,如果能够利用好swap分区,并且应用程序不会出现内存泄漏等问题时,可以缓解内存紧张的情况,但还是不能避免机器卡住的现象。另一方面,当机器卡住时,性能已经无法保证。
参考至:http://blog.chinaunix.net/uid-29634482-id-5127275.html
如有错误,欢迎指正
邮箱:czmc@163.com
相关推荐
Linux系统的OOM Killer处理机制 Linux系统的OOM(Out of Memory)Killer处理机制是一种内核机制,用于在系统内存不足时杀掉某个进程以腾出内存留给系统用,不致于让系统立刻崩溃。OOM Killer的触发条件是系统内存...
Linux内存管理机制包括多种层次和策略,旨在高效地分配和回收内存,避免内存耗尽和系统崩溃。本文将深入探讨Linux内存管理模型、伙伴系统、Slab分配流程以及内存回收策略。 首先,Linux内存管理模型将物理内存划分...
《理解Linux OOM Killer机制:从lab8_oom实验入手》 Linux操作系统的OOM (Out-Of-Memory) Killer是一个重要的内存管理机制,用于处理系统内存不足的情况。当系统资源极度紧张,无法分配新的内存时,OOM Killer会...
1. OOM Killer:当系统内存极度紧张时,Linux会启动Out-of-Memory Killer,选择优先级低或消耗内存过多的进程进行杀死,以释放内存。 2. 内存气泡:内存气泡是一种优化技术,它允许空闲内存从一个进程转移到另一个...
OOM Killer,全称为Out of Memory Killer,是Linux内核中的一种机制,用于处理系统内存不足的情况。当系统内存耗尽时,为了避免整个系统的崩溃,OOM Killer会选择并终止一些进程来释放内存,从而确保系统的稳定运行...
例如,理解Linux内核的oom killer机制,它根据每个进程的oom_score来决定优先杀死哪个进程。oom_score是基于进程的内存使用情况和其他因素计算出来的,较高的值表示更容易被杀死。 此外,内核层面的优化还包括调整...
在Linux系统中,当内存资源紧张,即将耗尽时,为避免系统崩溃,Linux内核引入了一种称为OOM (Out Of Memory) Killer的机制。OOM Killer会选择性地杀死某些进程以回收内存。这一机制主要针对系统可用内存(包括Swap...
OOM(Out of Memory)是Linux内存管理中的一种机制,用于描述内存不足的情况。KSM(Kernel Samepage Merging)是Linux内存管理中的一种机制,用于描述内存的共享机制。巨型页是Linux内存管理中的一种机制,用于描述...
当Linux系统面临内存不足的压力时,内核会启动一个称为“Out-of-Memory (OOM) Killer”的机制来防止系统崩溃。然而,OOM Killer可能会选择终止重要的进程,包括Erlang应用程序。针对这种情况,有一个名为“heart_oom...
当内存资源紧张,可能导致系统出现"out of memory"(OOM)错误时,Linux会执行内存回收策略。这包括释放不再使用的页面,或者优先回收低优先级进程的内存。此外,通过调整内存水位线,可以在内存使用接近极限时提前...
在后续章节中,我们将深入探讨Linux OOM Killer的工作机制,以及如何避免MySQL因内存不足而被杀死的情况。了解并正确配置这些设置对于确保RDS(如网易云关系数据库服务)的稳定运行至关重要。通过优化内存管理和理解...
Linux内核使用了一套复杂的内存管理子系统,包括slab分配器、伙伴系统和VMA(Virtual Memory Area)等机制来实现动态内存管理。 Slab分配器是Linux内核中用于高速缓存对象分配的机制。它预先分配一部分内存作为缓存...
本文总结了 Linux 操作系统的资源限制管理机制,涵盖了 page allocation failure、内存分配策略、OOM 杀死机制、进程优先级等方面的知识点。 一、Page Allocation Failure Page allocation failure 是 Linux 系统...
7. **OOM(Out-of-Memory)杀手**:当系统完全耗尽内存时,Linux内核会选择杀死某些进程以释放内存。内核根据一系列策略决定哪个进程应该被杀。 8. **缓存和缓冲区**:Linux内核使用缓存(如文件系统缓存)和缓冲区...
这份"Linux内核完全注释及linux内核源码"资料提供了宝贵的教育资源,帮助读者理解这个复杂的开源项目的内部运作机制。 首先,让我们来看看Linux内核的基本组成部分: 1. **进程管理**:Linux内核通过调度算法控制...
《深入理解Linux内核》详细介绍了Linux中的各种文件系统,如EXT2、EXT3、EXT4,以及VFAT和NTFS等Windows文件系统的支持。书中讨论了文件系统的数据结构、挂载和卸载过程、文件的创建和删除,以及缓存机制等,这些...
包括分页机制、地址空间布局、交换和OOM(Out of Memory)处理。 4. **虚拟文件系统(VFS)**:VFS是Linux内核提供的一种抽象层,允许支持多种不同的文件系统。它定义了一套通用的接口,使得不同文件系统间的操作变...
3. 低内存管理器(Low Memory Killer):不同于Linux的OOM机制,Android的低内存杀手更灵活,可以根据需要智能地结束进程,以防止系统因内存不足而崩溃。它能够动态调整内存压力阈值,以确保关键服务的运行。 4. ...
当物理内存不足时,Linux会通过OOM(Out-of-Memory)杀手或交换机制来缓解内存压力。OOM killer会选择优先级低的进程终止,以释放内存,而交换则会将部分内存内容写入交换分区。 8. **内存分配函数(Memory ...
8. OOM(Out-Of-Memory)杀手:当系统内存耗尽时,Linux会启动OOM killer,选择杀死一些进程以释放内存。选择哪个进程被杀取决于其内存使用情况和优先级。 9. 内存管理工具:`free`命令显示当前系统的内存使用情况...