Linux Top命令之load average详解

前言

因为笔者面试中被问到了这个问题,感觉自己不是很清楚,所以还是整理一下,博客中也有不少讲到top命令的,但是几乎没看到有把load average这个讲清楚的,所以还是有必要来篇水文。

进入正题

由于这里只是分析load average,具体怎么使用top,大家应该都有所了解,我这里就不再赘述,重点分析一下load average.
我们都知道load average分别代表最近一分钟、最近5分钟、最近15分钟的负载。但是有的负载值才0.01,有的负载值可以到1,有的甚至可以到5.这到底是什么意思呢?当负载数大于1的时候是不是就预示着系统负载很高?是不是疑惑中又夹杂着一点喜悦呢?因为你马上就要知道”谜底“了。开个玩笑,嘿嘿!

1.先查看一下cpu核数

我这里使用的是阿里云的centos7

cat /proc/cpuinfo |grep "cpu core"|wc -l
2

2.看一下是否开启超线程

cat /proc/cpuinfo | grep "processor" | wc -l
2

显然没有开启超线程,因为cpu线程数和cpu核数相同。

3.开始测试

public class Top {

    public static void main(String[] args) {
         new Thread(new Runnable() {
             public void run() {
                while(true){

                }

             }
         }).start();

        new Thread(new Runnable() {
            public void run() {
                while(true){

                }
            }
        }).start();
    }
}

启动两个线程一直做空轮询,然后通过top查看发现一分钟左右load average第一个参数停留在1.98左右,后面两位数字也在慢慢上升。

启动一个线程试一下。

public class Top {

    public static void main(String[] args) {
         new Thread(new Runnable() {
             public void run() {
                while(true){

                }

             }
         }).start();
    }
}

一分钟左右查看top:

top - 12:39:03 up 42 days, 14:15,  2 users,  load average: 1.03, 0.63, 0.38

最近一分钟左右的负载基本稳定在1左右,正好是2线程同时运行时的一半。

是不是可以下结论说:linux top的load average和cpu核数有关,满负载的值就是cpu的个数呢?其实也不能完全这么说,因为还是load average大于cpu核数的情况,再来做个试验,起5个线程:

     for(int i=0;i<5;i++){
            new Thread(new Runnable() {
                public void run() {
                    while(true){

                    }

                }
            }).start();
        }

大概运行了1-2分钟,top查看一下:

top - 12:49:24 up 42 days, 14:25,  2 users,  load average: 4.96, 2.39, 1.18
Tasks:  76 total,   1 running,  75 sleeping,   0 stopped,   0 zombie
%Cpu0  :  99.7/0.3   100[||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||]
%Cpu1  :  99.3/0.7   100[||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||]
KiB Mem :  3881920 total,   921592 free,  2109728 used,   850600 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  1531428 avail Mem 

发现负载基本上就稳定为5了。可知load average和线程数基本相等。

更深一层

static int loadavg_proc_show(struct seq_file *m, void *v)
{
    unsigned long avnrun[3];

    get_avenrun(avnrun, FIXED_1/200, 0);

    seq_printf(m, "%lu.%02lu %lu.%02lu %lu.%02lu %ld/%d %d\n",
        LOAD_INT(avnrun[0]), LOAD_FRAC(avnrun[0]),
        LOAD_INT(avnrun[1]), LOAD_FRAC(avnrun[1]),
        LOAD_INT(avnrun[2]), LOAD_FRAC(avnrun[2]),
        nr_running(), nr_threads,
        idr_get_cursor(&task_active_pid_ns(current)->idr) - 1);
    return 0;
}

这是top输出到控制台的代码,发现数据是从avnrun数组中取出来的,找到数组avnrun赋值的地方:

    if (!time_before(jiffies, sample_window + 10)) {
        /*
         * Catch-up, fold however many we are behind still
         */
        delta = jiffies - sample_window - 10;
        n = 1 + (delta / LOAD_FREQ);

        active = atomic_long_read(&calc_load_tasks);
        active = active > 0 ? active * FIXED_1 : 0;

        avenrun[0] = calc_load_n(avenrun[0], EXP_1, active, n);
        avenrun[1] = calc_load_n(avenrun[1], EXP_5, active, n);
        avenrun[2] = calc_load_n(avenrun[2], EXP_15, active, n);

        WRITE_ONCE(calc_load_update, sample_window + n * LOAD_FREQ);
    }

找到calc_load_n(avenrun[0], EXP_1, active, n)就大致明白了load average的值和当前执行的任务数有关,具体atomic_long_read方法内的逻辑,其实没必要关心,有兴趣的可以自行查看。

结论

Linux top命令的load average满负荷是cpu核心的个数,实际上应该比满负荷的值要小,不然会影响性能。如果负载超过cpu核心数的话,则说明系统超负荷运行。而负载最大值和并发执行的线程数有关,大小基本和并发执行的线程数一致。有了对load average的大致了解后,就可以判断出系统的性能状况,好做出相应的调整。现在来回答开篇提到的那个问题是否load average大于1(小于2)就是系统负载比较高就非常容易了。首先要看一下cpu的核数和线程数,如果是单核CPU,负载等于1就是满负荷运转了,如果是四核、甚至更多核心的CPU,负载大于1这说明系统当前负载很小,不需要过多关心。文中如果有什么错误的地方,还请提出,谢谢~

  • 6
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值