Linux内核OOM机制的详细分析

Linux 内核有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了防止内存耗尽而内核会把该进程杀掉。典型的情况是:某天一台机器突然ssh远程登录不了,但能ping通,说明不是网络的故障,原因是sshd进程被OOM killer杀掉了(多次遇到这样的假死状况)。重启机器后查看系统日志/var/log/messages会发现Out of Memory: Kill process 1865(sshd)类似的错误信息。


防止重要的系统进程触发(OOM)机制而被杀死:可以设置参数/proc/PID/oom_adj-17,可临时关闭linux内核的OOM机制内核会通过特定的算法给每个进程计算一个分数来决定杀哪个进程,每个进程的oom分数可以/proc/PID/oom_score中找到。我们运维过程中保护的一般是sshd和一些管理agent

 

保护某个进程不被内核杀掉可以这样操作:

点击(此处)折叠或打开

echo -17 > /proc/$PID/oom_adj

如何防止sshd被杀,可以这样操作:

点击(此处)折叠或打开

pgrep -f "/usr/sbin/sshd" | while read PID;do echo -17 > /proc/$PID/oom_adj;done

可以在计划任务里加入这样一条定时任务,就更安全了:

点击(此处)折叠或打开

#/etc/cron.d/oom_disable

*/1**** root pgrep -f "/usr/sbin/sshd" | while read PID;do echo -17 > /proc/$PID/oom_adj;done

为了避免重启失效,可以写入/etc/rc.d/rc.local

点击(此处)折叠或打开

echo -17 > /proc/$(pidof sshd)/oom_adj

至于为什么用-17而不用其他数值(默认值为0),这个是由linux内核定义的,查看内核源码可知:
以linux-3.3.6版本的kernel源码为例,路径为linux-3.6.6/include/linux/oom.h,阅读内核源码可知oom_adj的可调值为15到-16,其中15最大-16最小,-17为禁止使用OOM。oom_score为2的n次方计算出来的,其中n就是进程的oom_adj值,所以oom_score的分数越高就越会被内核优先杀掉。

 
当然还可以通过修改内核参数禁止OOM机制

点击(此处)折叠或打开

# sysctl -w vm.panic_on_oom=1
vm.panic_on_oom = 1 //1表示关闭,默认为0表示开启OOM
 
# sysctl -p
 
为了验证OOM机制的效果,我们不妨做个测试。

首先看看我系统现有内存大小,没错96G多,物理上还要比查看的值大一些。

 

再看看目前进程最大的有哪些,top查看,我目前只跑了两个java程序的进程,分别4.6G,再往后redis进程吃了21m,iscsi服务占了32m,gdm占了25m,其它的进程都是几M而已。

 

现在我自己用C写一个叫bigmem程序,我指定该程序分配内存85G,呵呵,效果明显,然后执行后再用top查看,排在第一位的是我的bigmem,RES是物理内存,已经吃满了85G。

 

继续观察,当bigmem稳定保持在85G一会后,内核会自动将其进程kill掉,增长的过程中没有被杀,如果不希望被杀可以执行

点击(此处)折叠或打开

pgrep -f "bigmem" | while read PID; do echo -17 > /proc/$PID/oom_adj;done

执行以上命令前后,明显会对比出效果,就可以体会到内核OOM机制的实际作用了。

 

注意:

1.Kernel-2.6.26之前版本的oomkiller算法不够精确,RHEL 6.x版本的2.6.32可以解决这个问题。

2.子进程会继承父进程的oom_adj。

3.OOM不适合于解决内存泄漏(Memory leak)的问题。

4.有时free查看还有充足的内存,但还是会触发OOM,是因为该进程可能占用了特殊的内存地址空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/444868.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法(18)-leetcode-剑指offer2

leetcode-剑指offer-211.面试题13-机器人的运动范围-广度优先搜索12.面试题14-1-剪绳子13.面试题14-2-剪绳子214.面试题16-二进制中1的个数-布莱恩克尼根15.面试题16-数值的整数次方-快速幂解析法16.面试题17-打印从1到最大的n位数17.面试题18-删除链表的节点18.面试题19-正则匹…

rabbitmq技术的一些感悟(一)

Rabbitmq 初识rabbitmq RabbitMQ是流行的开源消息队列系统,用erlang语言开发。RabbitMQ是AMQP(高级消息队列协议)的标准实现。如果不熟悉AMQP,直接看RabbitMQ的文档会比较困难。不过它也只有几个关键概念,这里简单介绍 几个概念说明: Broker

leetcode21 合并两个链表

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 思路:链表归并。 /*** Definition for si…

rabbitmq技术的一些感悟(二)

上一节文章主要是说了一下rabbitmq的安装以及搭建好环境的一些命令,以及常用的api调用,其实自从google被封掉之后,我之前收藏的很多技术连接都已经被禁止访问了,这个是多么可悲的一件事情啊,说多了都是泪。 首先,我先写一段消费者的模块,建立连接,初始化amq以及销毁连接…

算法(19)-leetcode-剑指offer3

leetcode-剑指offer-321.面试题22-链表中的倒数第k个节点22.面试题24-反转链表23.面试题25-合并两个排序链表-递归24.面试题26-树的子结构25.面试题27-二叉树的镜像26.面试题28-对称二叉树27.面试题29-顺时针打印矩阵28.面试题30-包含min函数的栈29.面试题31-栈的押入&#xff…

高效解析xml的总结,闲下来写的

需要这么几个库&#xff0c;直接放在你的代码工程里即可&#xff1a; #include "rapidxml.h" #include "rapidxml_utils.h" int ReBornBossConf::loadConf(const char* szFileName){ rapidxml::file<char> fdoc(szFileName); rapidxml::xml_docum…

leetcode35 插入的位置

给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 你可以假设数组中无重复元素。 思路&#xff1a;二分查找 public class Solution {public int searchInsert(i…

算法(20)-leetcode-剑指offer4

leetcode-剑指offer-433.面试题33-二叉搜索树的后序遍历序列34.面试题34-二叉树中和为某一值的路径35.面试题35-复杂链表的复制36.面试题36-二叉搜索树与双向链表37.面试题37-序列化二叉树38.面试题38-字符串的排列39.面试题39-数组中出现次数超过一半的数字40.面试题40-最小的…

关于linux的进程中的各个线程cpu占用情况的分析和查看

我们经常会在新开的服搭建一个游戏的服务器,有时候要进行压力测试,那么如何来看呢,一般我们会通过top命令查看各个进程的cpu和内存占用情况,获得到了我们的进程id,然后我们也许会通过pstack命令查看里边的各个线程id以及对应的线程现在正在做什么事情,分析多组数据就可以…

算法(21)-leetcode-剑指offer5

leetcode-剑指offer-443.面试题43-1&#xff5e;n整数中1出现的次数44.面试题44-数字序列中某一位的数字45.面试题45-把数组排成最小的数-快排变种46.面试题46-把数字翻译成字符串47.面试题47-礼物的最大价值-dp48.面试题48-最长不含重复字符的子字符串-滑动窗口法49.面试题49-…

游戏中DDA算法和Bresenham算法的应用

在角色扮演或即时战略游戏中,经常会将角色以最佳的方式走到指定地点。游戏场景的地面情况复杂,而且场面大,若采用盲目式搜索,例如盲目穷举法,则几乎要遍历整个场景,效率非常低,造成角色反应速度过慢,实践证明是一种不适合网络游戏寻路方法。而启发式搜索算法在障碍较少的情况下…

leetcode7 整数反转

给出一个 32 位的有符号整数&#xff0c;你需要将这个整数中每位上的数字进行反转。 示例 1: 输入: 123 输出: 321 示例 2: 输入: -123 输出: -321 示例 3: 输入: 120 输出: 21 注意: 假设我们的环境只能存储得下 32 位的有符号整数&#xff0c;则其数值范围为 [−231, …

关于苹果purchase的验证

用户在购买苹果的商品的过程如下:

算法(23)-leetcode-剑指offer7

leetcode-剑指offer-559.面试题59-队列的最大值60.面试题64-求12...n61.面试题65-不用加减乘除做加法62.面试题66-构建乘积数组63.面试题68-1二叉树搜索树的最近公共祖先64.面试题68-2二叉树的最近公共祖先65.面试题67-把字符串转换成数字-自动机66.面试题20-表示数值的字符串-…

C/C++ 获得公网ip地址和内网ip

获得公网ip:bool getPublicIp(string& ip) {int sock;char **pptr = NULL;struct sockaddr_in destAddr;struct hostent *ptr = NULL;char destIP[128];sock = socket(AF_INET,SOCK_STREAM,0);if( -1 == sock ){perror("creat socket failed");return …

终于,我读懂了所有Java集合——List篇

ArrayList 基于数组实现&#xff0c;无容量的限制。 在执行插入元素时可能要扩容&#xff0c;在删除元素时并不会减小数组的容量&#xff0c;在查找元素时要遍历数组&#xff0c;对于非null的元素采取equals的方式寻找。 是非线程安全的。 注意点&#xff1a; &#xff08…

关于长连接和短连接

短连接 连接->传输数据->关闭连接 HTTP是无状态的,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。 也可以这样说:短连接是指SOCKET连接后发送后接收完数据后马上断开连接。

C++(8)--数组array-长度固定

数组及常用算法1.数组基本概念2.一维数组2.1数组的定义2.2数组初始化2.3一维数组动态赋初值2.4一维数组应用实例2.5一维数组的排序算法2.6 一维数组元素的删除和插入array3.二维数组3.1数组定义3.2二维数组的动态赋值《老九学堂C课程》《C primer》学习笔记。《老九学堂C课程》…

关于去苹果服务器验证充值的一些看法

前端时间看了下关于app充值验证发送游戏金币的好多帖子和文章,也总结了一下app校验的php代码:可以参考我的上一封博客: http://blog.csdn.net/pbymw8iwm/article/details/42167125 其中这个帖子回复的大神比较多:点击打开链接 有些人认为拿苹果的receptdata去验证,通过返…

终于,我读懂了所有Java集合——queue篇

Stack 基于Vector实现&#xff0c;支持LIFO。 类声明 public class Stack<E> extends Vector<E> {} push public E push(E item) {addElement(item);return item; } pop public synchronized E pop() {E obj;int len size();obj peek();removeElementAt(…