Top命令学习

top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。

这里,我对top命令中所展示的信息做一个简要梳理。

我们可以把top信息分为两个部分,第一部分是系统信息,第二部分是进程信息。

upload successful

1 系统信息

在上半部分,显示的系统信息。

1.1 系统时间、用户数和系统负载

top - 18:13:21 up 10 days, 21:24, 2 users, load average: 0.00, 0.01, 0.05

18:13:21 指的是系统当前时间,up 10 days, 21:24指的是系统从启动到现在经历过的时间。

2 users指的是当前登录的用户数。

load average: 0.00, 0.01, 0.05指的是当前系统的负载情况。其中三个数值分别代表系统1分钟、5分钟、15分钟的CPU负载信息。

注:上边的信息也可以通过uptime命令来拿到。

1.1.1 用户信息

通过who命令也可获取到当前登录的用户信息。

upload successful

pts表示使用SSH远程登录而来,第三列表示登录时间,第四列表示是从哪个IP登录而来。

通过w命令可以获取登录用户的更多信息

upload successful

最后一列是该用户执行的信息,什么都没做显示的是-bash

使用history命令获取当前用户的操作历史,查看~/.bash_history也可以获取同样的记录。

1.1.2 系统负载

load是什么?

以单核CPU为例,单核CPU的load满载为1,表示每个处理时刻的cpu都有任务要处理。load可以大于1,大于1说明有任务没有被IO阻塞,而是受限于CPU性能。

Linux命令中获取的系统负载,实际上都取自/proc/loadavg。在/proc/目录中,mount的是一种叫proc的Linux伪文件系统,主要被用作获取内核数据结构的接口。

要了解/proc/loadavg逻辑,可以直接查看对应的内核代码Linux v5.5 fs/proc/loadavg.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
}

avenrun数组中的高21位存放的是整数,低11位存放的是小数,avenrun数组是由操作系统每5s刷新产生。他的计算公式比较复杂,但整体上是和操作系统中运行中任务数(TASK_RUNNING)不可中断的睡眠任务数(TASK_UNINTERRUPTIBLE)正相关。

一般情况下,单核CPU的load应该在1以下。0.7-1之间是比较合适的区间。当load=1时,说明系统已经没有额外的资源处理任务。当load>5,说明系统已经不堪重负。

通常情况下,我们最关心的还是load15,如果load15过高,说明系统处于高位很久了。之后再看看load5和load1,如果已经恢复到正常水平,那么就不要紧。

进程含义

upload successful

  • TASK_RUNNING 进程处于运行(它是系统的当前进程)或者准备运行状态(它在等待系统将CPU分配给它)
  • TASK_INTERRUPTIBLE 等待某个条件:中断、信号或能唤醒进程的资源
  • TASK_UNINTERRUPTIBLE 处于睡眠状态,信号无法唤醒它。
  • TASK_STOPPED 进程停止,当进程收到SIGSTOP、SIGTSTP、SIGTTIN或SIGTTOU信号时就会进入次状态
  • TASK_TRACED 进程执行被调试器停止(调试程序使用ptrace()系统调用来监控程序)
  • EXIT_ZOMBIE 进程执行停止,但父进程还没调用wait4()或waitpid()来获取该进程返回信息。
  • EXIT_DEAD 进程的最终状态,父进程调用wait4()或waitpid()来获取该进程返回信息,内核即将移除该进程。

1.2 任务信息

Tasks: 241 total, 1 running, 240 sleeping, 0 stopped, 0 zombie

在第二行,显示的是操作系统当前的任务总数、正在运行的任务数、处于睡眠状态的任务数、停止的任务数、僵死的任务数。

1.3 CPU信息

%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

在第三行,显示的是cpu的一些信息。

要理解CPU信息,就需要先了解Kernel space和User space。简单来说,Kernel space 是 Linux 内核的运行空间,User space 是用户程序的运行空间。为了安全,它们是隔离的,即使用户的程序崩溃了,内核也不受影响。Kernel space 可以执行任意命令,调用系统的一切资源;User space 只能执行简单的运算,不能直接调用系统资源,必须通过系统接口(又称 system call),才能向内核发出指令。再简单来说,就是各类加减乘除都是在用户空间进行的,而读写文件、网络IO都是需要切换到内核空间执行。

例如:在cp文件时,需要先将文件拷贝到内核空间的buffer上,再拷贝到用户空间的buffer上,之后再反过来,从用户空间buffer拷贝到内核空间buffer,最终再写到磁盘上。

上面这个例子中,等待打开文件属于wa,读取文件内容到内核空间buffer再同步到用户空间buffer属于sy,用户空间buffer之间转移属于us。

  • us(user)CPU在用户空间运行时间百分比,但不包含renice值为负的任务占用的CPU的时间。
  • sy(system)CPU在内核空间运行时间百分比。
  • ni(nice)改变过优先级的进程占用CPU的百分比。范围是-20(最高优先级)到19(最低优先级)。
  • id(idle)空闲CPU时间百分比。这个值越高,说明CPU越闲。
  • wa(wait)CPU等待I/O时间百分比。wa过高说明IO性能有问题。
  • hi(hard interrupt)CPU硬中断时间百分比。
  • si(soft interrupt)CPU软中断时间百分比。
  • st(stole time)只对虚拟机有效,表示分配给当前虚拟机的 CPU 时间之中,被同一台物理机上的其他虚拟机偷走的时间百分比

top默认显示的数据是所有cpu的平均值,如果想看每一个cpu的处理情况,按1即可,再按1返回;

1.4 内存信息和交换空间

1
2
KiB Mem :  2027952 total,   109736 free,  1137384 used,   780832 buff/cache
KiB Swap: 4194300 total, 4176124 free, 18176 used. 641044 avail Mem

内存信息的单位是KiB

  • total 当前系统管理的物理内存大小,上边的内存总量是2GB。
  • free 空闲的物理内存量,上边的空闲内存是100MB+。
  • used 使用的物理内存量,上边的使用内存是1GB+。
  • buff/cache 用作内核缓存的物理内存量,上边的换存量是760MB+。

交换空间的单位也是KiB

  • total 当前系统管理的交换空间大小,上边的交换空间总量是4GB。
  • free 空闲的交换空间内存量,上边的空闲内存是4GB。
  • used 使用的交换空间内存量,上边的使用内存是17MB+。
  • avail Mem 可用于进程下一次分配的物理内存量,上边的可分配量是620MB+。

先来看看内存空间,total=used+free。但buff和cache是什么意思?

在Linux中,操作系统会把读取过的数据都缓存起来,以便下次读取时减少读取时间。即使程序运行结束,内存也不会自动释放。而buff和cache就是linux的缓存内存,这部分缓存内存会在其他程序需要更多内存,但free内存不够时被释放。

所以程序真实使用的内存数应该是real-used = used-buff-cache。上面的例子真实使用内存应该是340MB+。

我们也可以使用free -m来查看内存情况。

upload successful

buff和cache的用途不同。buff是用来处理两个系统间速度不均衡的缓存,例如网卡的数据会存满一个buffer后,再由系统处理。cache是从硬盘读取文件到内存的缓存,例如使用vim编辑一个文件,这个文件就会被加载到内存。

2 进程信息

1
2
3
4
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
1491 mysql 20 0 2686220 116436 6264 S 0.3 5.7 12:14.69 mysqld
72189 root 20 0 0 0 0 S 0.3 0.0 0:12.23 kworker/0:0
1 root 20 0 191164 3296 2052 S 0.0 0.2 0:13.91 systemd

我们来分别看看每列的含义

  • PID:进程的ID
  • USER:进程所有者
  • PR:进程的优先级别,越小越优先被执行
  • NI:nice值
  • VIRT:进程占用的虚拟内存,和RES加起来构成申请内存数。
  • RES:进程占用的物理内存,指的是实际使用数,而不是申请内存数。
  • SHR:进程使用的共享内存,进程单独占有的物理内存公式:RES-SHR。
  • S:进程的状态。S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值为负数
  • %CPU:进程占用CPU的使用率
  • %MEM:进程使用的物理内存和总内存的百分比
  • TIME+:该进程启动后占用的总的CPU时间,即占用CPU使用时间的累加值。
  • COMMAND:进程启动命令名称

调整优先级的方式

  • 启动:nice -n -20 xxx
  • 修改:renice -20 -p pid

查看进程详细信息

查看全部进程信息,包含进程所有者、PID、PPID、启动以来耗费CPU时间、CMD等

1
ps -ef

3 参考