• nice -n 10 bash 和 chrt 10 bash 和 echo -17 > /proc/PID/oom_score_adj


    进程优先级起作用的方式从发明以来基本没有什么变化,无论是只有一个cpu的时代,还是多核cpu时代,都是通过控制进程占用cpu时间的长短来实现的。

    就是说在同一个调度周期中,优先级高的进程占用的时间长些,而优先级低的进程占用的短些。

    请大家真的不要混淆了系统中的这两个概念:nice(NI)和priority(PR),他们有着千丝万缕的关系,但对于当前的Linux系统来说,它们并不是同一个概念。

    什么是NICE值?

    NICE值应该是熟悉Linux/UNIX的人很了解的概念了,它是反应一个进程“优先级”状态的值,其取值范围是-20至19,一共40个级别。

    这个值越小,表示进程”优先级”越高,而值越大“优先级”越低。

    例如,我们可以通过NICE命令来对一个将要执行的bash命令进行NICE值设置,方法是:

    1. [root@zorrozou-pc0 zorro]# nice -n 10 bash 

    这样我就又打开了一个bash,并且其nice值设置为10,而默认情况下,进程的优先级应该是从父进程继承来的,这个值一般是0。

    nice值虽然不是priority,但是它确实可以影响进程的优先级。

    在英语中,如果我们形容一个人nice,那一般说明这个人的人缘比较好。什么样的人人缘好?往往是谦让、有礼貌的人。

    比如,你跟一个nice的人一起去吃午饭,点了两个一样的饭,先上了一份后,nice的那位一般都会说:“你先吃你先吃!”,这就是人缘好,这人nice!但是如果另一份上的很晚,那么这位nice的人就要饿着了。

    这说明什么?

    越nice的人抢占资源的能力就越差,而越不nice的人抢占能力就越强。这就是nice值大小的含义,nice值越低,说明进程越不nice,抢占cpu的能力就越强,优先级就越高(作者这个解释太形象了,小编忍不住要手动点赞!!)。

    在原来使用O1调度的Linux上,我们还会把nice值叫做静态优先级,这也基本符合nice值的特点,就是当nice值设定好了之后,除非我们用renice去改它,否则它是不变的。

    而priority的值在之前内核的O1调度器上表现是会变化的,所以也叫做动态优先级

    什么是优先级和实时进程?

    我们再来看看什么是priority值,就是ps命令中看到的PRI值或者top命令中看到的PR值。

    本文为了区分这些概念,以后:

    • 统一用nice值表示NI值,或者叫做静态优先级,也就是用nice和renice命令来调整的优先级;
    • 而实用priority值表示PRI和PR值,或者叫动态优先级。
    • 我们也统一将“优先级”这个词的概念规定为表示priority值的意思

    说白了就是,Linux实际上实现了140个优先级范围,取值范围是从0-139,这个值越小,优先级越高。nice值的-20到19,映射到实际的优先级范围是100-139。

    新产生进程的默认优先级被定义为:

    1. #define DEFAULT_PRIO (MAX_RT_PRIO + NICE_WIDTH / 2) 

    实际上对应的就是nice值的0。

    正常情况下,任何一个进程的优先级都是这个值,即使我们通过nice和renice命令调整了进程的优先级,它的取值范围也不会超出100-139的范围,除非这个进程是一个实时进程,那么它的优先级取值才会变成0-99这个范围中的一个。

    所有优先级值在0-99范围内的,都是实时进程,所以这个优先级范围也可以叫做实时进程优先级,而100-139范围内的是非实时进程。

    系统的整体优先级策略是:

    • 如果系统中存在需要执行的实时进程,则优先执行实时进程。
    • 直到实时进程退出或者主动让出CPU时,才会调度执行非实时进程。

    实时进程可以指定的优先级范围为1-99,将一个要执行的程序以实时方式执行的方法为:

    1. [root@zorrozou-pc0 zorro]# chrt 10 bash 
    2. [root@zorrozou-pc0 zorro]# chrt -p $$ 
    3. pid 14840's current scheduling policy: SCHED_RR 
    4. pid 14840's current scheduling priority: 10 

    可以看到,新打开的bash已经是实时进程,默认调度策略为SCHED_RR,优先级为10。如果想修改调度策略,就加个参数:

    1. [root@zorrozou-pc0 zorro]# chrt -f 10 bash 
    2. [root@zorrozou-pc0 zorro]# chrt -p $$ 
    3. pid 14843's current scheduling policy: SCHED_FIFO 
    4. pid 14843's current scheduling priority: 10 

    linux下允许程序申请比系统可用内存更多的内存,这个特性叫Overcommit。这样做是出于优化系统考虑,因为不是所有的程序申请了内存就立刻使用的,当你使用的时候说不定系统已经回收了一些资源了。不幸的是,当你用到这个Overcommit给你的内存的时候,系统还没有资源的话,OOM killer就跳出来了。

    参数/proc/sys/vm/overcommit_memory可以控制进程对内存过量使用的应对策略
    1.当overcommit_memory=0 允许进程轻微过量使用内存,但对于大量过载请求则不允许,也就是当内存消耗过大就是触发OOM killer。
    2.当overcommit_memory=1 永远允许进程overcommit,不会触发OOM killer。
    3.当overcommit_memory=2 永远禁止overcommit,不会触发OOM killer。

    当然,如果触发了OOM机制,系统会杀掉某些进程,那么什么进程会被处理掉呢?kernel提供给用户态的/proc下的一些参数:
    1./proc/[pid]/oom_adj,该pid进程被oom killer杀掉的权重,介于 [-17,15](具体具体权重的范围需要查看内核确认)之间,越高的权重,意味着更可能被oom killer选中,-17表示禁止被kill掉。

    通过2个步骤可以确认,具体权重的范围:

    ①uname -a查看Linux内核版本

    ②进入/usr/src/kernels/内核版本/include/linux/oom.h确认具体的权重范围

    2./proc/[pid]/oom_score,当前该pid进程的被kill的分数,越高的分数意味着越可能被kill,这个数值是根据oom_adj运算(2ⁿ,n就是oom_adj的值)后的结果。

    oom_adj,oom_score是oom_killer的主要参考值

     
    So(我们能做什么):
    1.保护我们重要的进程,避免被处理掉
    实例:
    ps -ef|grep GameServer(获得重要进程的PID)
    echo -17 > /proc/PID/oom_score_adj(输入-17,禁止被OOM机制处理)
    2.关闭OOM机制(不推荐,如果不启动OOM机制,内存使用过大,会让系统产生很多异常数据)
    echo "vm.panic_on_oom=1" >> /etc/sysctl.conf
    systcl -p
     

    vm.panic_on_oom    默认为0开启    为1时表示关闭此功能

    等于0时,表示当内存耗尽时,内核会触发OOM killer杀掉最耗内存的进程。

    当OOM Killer被启动时,通过观察进程自动计算得出各当前进程的得分 /proc/<PID>/oom_score,分值越高越容易被kill掉。

  • 相关阅读:
    The best programmers are the quickest to Google
    NetBeans 时事通讯(刊号 # 117 Sep 16, 2010)
    Apache HttpClient 4.0.3 GA 发布
    warning LNK4070的解决办法
    看泡沫
    早秋精神
    NetBeans 时事通讯(刊号 # 117 Sep 16, 2010)
    Maven 3.0 RC1 发布
    关于类的数据成员的访问权限设计的一些思考
    看泡沫
  • 原文地址:https://www.cnblogs.com/gaoyuechen/p/11428402.html
Copyright © 2020-2023  润新知