TOP命令详解

top命令经常用来监控linux的系统状况,是常用的性能分析工具,能够实时显示系统中各个进程的资源占用情况。

top的使用方式 top [-d number] | top [-bnp]

参数解释:

  • -d:number代表秒数,表示top命令显示的页面更新一次的间隔。默认是5秒。
  • -b:以批次的方式执行top。
  • -n:与-b配合使用,表示需要进行几次top命令的输出结果。
  • -p:指定特定的pid进程号进行观察。

在top命令显示的页面还可以输入以下按键执行相应的功能(注意大小写区分的):

  • ?:显示在top当中可以输入的命令
  • P:以CPU的使用资源降序排序显示,默认
  • M:以内存的使用资源降序排序显示
  • N:以pid降序排序显示
  • T:由进程使用的时间累计排序显示
  • k:给某一个pid一个信号。可以用来杀死进程
  • r:给某个pid重新定制一个nice值(即优先级)
  • q:退出top(用ctrl+c也可以退出top)。
  • 1:数字1,可以查看CPU核心的个数及详细信息

实例:

# top          	   //每隔5秒显式所有进程的资源占用情况
# top -d 2         //每隔2秒显式所有进程的资源占用情况
# top -c           //每隔5秒显式进程的资源占用情况,并显示进程的命令行参数(默认只有进程名)
# top -p 12345 -p 6789        //每隔5秒显示pid是12345和pid是6789的两个进程的资源占用情况
# top -d 2 -c -p 123456       //每隔2秒显示pid是12345的进程的资源使用情况,并显式该进程启动的命令行参数
# top -Hp 进程id   // 显示某个进程下所有线程的资源占用情况
一、top前5行统计信息

第1行是任务队列信息,其参数如下:

在这里插入图片描述

内容含义
21:15:31表示当前时间
up 180 days, 10:01系统运行时间 格式为时:分,运行了180天10小时1分钟
1 users当前登录用户数
load average: 0.00, 0.01, 0.05系统平均负载,即任务队列的平均长度。 三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值。

什么是系统平均负载?平均负载可以理解为当前系统的平均活跃进程数,包含了系统处于可运行状态和不可中断状态的平均进程数,就是平均活跃进程数。

那么知道了什么是系统平均负载,那么它为多少时代表我们的系统负载较高呢?比如,此时1分钟的平均负载为5.6,而我们的操作系统是4个CPU,那么就代表此时系统负载过高,意味着有160%的的超载进程竞争不到CPU;若负载为2.0,则意味着有50%的CPU空闲。1分钟的系统负荷只是暂时现象,问题不大。应该主要观察"15分钟系统负荷",将它作为服务器正常运行的指标。

第2、3行为进程和CPU的信息 :
当有多个CPU时,这些内容可能会超过两行,其参数如下:

在这里插入图片描述

内容含义
108 total进程总数
2 running正在运行的进程数
106 sleeping睡眠的进程数
0 stopped停止的进程数
0 zombie僵尸进程数
内容含义
0.0 us用户空间占用CPU百分比
0.0 sy内核空间占用百分比
0.0 ni用户进程内改变过优先级的进程占用CPU百分比
100.0 id空闲CPU百分比
0.0 wa等待输入输出的CPU时间百分比
0.0 hi硬中断(Hardware IRQ)占用CPU的百分比
0.0 si软中断(Software Interrupts)占用CPU的百分比
0.0 st虚拟机占用百分比

第4、5行为内存信息,其参数如下 :
在这里插入图片描述

内容含义
KiB Mem: 3880176 total物理内存总量,单位:B
166316 free空闲的物理内存总量,单位:B
772292 used使用的物理内存总量,单位:B
2941568 buff/cache用作内核缓存的内存总量,单位:B
内容含义
KiB Swap: 0 total交换区总量,单位:B
0 free空闲的交换区总量,单位:B
0 used使用的交换区总量,单位:B
2809396 avail Mem代表可用于进程下一次分配的物理内存数量
二、进程信息:

在这里插入图片描述

内容含义
PID进程id
USER进程所有者的用户名
PR优先级
NInice值,负值表示高优先级,正值表示低优先级
VIRT进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
RES进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
SHR共享内存大小,单位kb
S进程状态。D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程
%CPU上次更新到现在的CPU时间占用百分比
%MEM进程使用的物理内存百分比
TIME+进程使用的CPU时间总计,单位1/100秒
COMMAND命令名/命令行
SWAP进程使用的虚拟内存中,被换出的大小,单位kb
CODE可执行代码占用的物理内存大小,单位kb
DATA可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb
RUSERReal user name
UID进程所有者的用户id
GROUP进程所有者的组名
TTY启动进程的终端名。不是从终端启动的进程则显示为 ?
P最后使用的CPU,仅在多CPU环境下有意义
TIME进程使用的CPU时间总计,单位秒
nFLT页面错误次数
nDRT最后一次写入到现在,被修改过的页面数。
WCHAN若该进程在睡眠,则显示睡眠中的系统函数名
Flags任务标志
三、进程的状态:
  • R 是 Running 或 Runnable 的缩写,表示进程在 CPU 的就绪队列中,正在运行或者正在等待运行。
  • D 是 Disk Sleep 的缩写,也就是不可中断状态睡眠(Uninterruptible Sleep),一般表示进程正在跟硬件交互,并且交互过程不允许被其他进程或中断打断。
  • Z 是 Zombie 的缩写,它表示僵尸进程,也就是进程实际上已经结束了,但是父进程还没有回收它的资源(比如进程的描述符、PID 等)。
  • S 是 Interruptible Sleep 的缩写,也就是可中断状态睡眠,表示进程因为等待某个事件而被系统挂起。当进程等待的事件发生时,它会被唤醒并进入 R 状态。
  • I 是 Idle 的缩写,也就是空闲状态,用在不可中断睡眠的内核线程上。硬件交互导致的不可中断进程用 D 表示,但对某些内核线程来说,它们有可能实际上并没有任何负载,用 Idle 正是为了区分这种情况。D 状态的进程会导致平均负载升高, I 状态的进程却不会。
四、CPU使用率过高排查思路:
1.使用top命令,然后按P按照CPU使用率降序排序,找到占用CPU过高的进程id
2.使用`ps -mp [进程id] -o THREAD,tid,time | sort -rm`获取线程信息,并找到占用CPU高的线程
3.使用`echo 'obase=16;[线程id]' | bc``echo 'obase=16;[线程id]' | printf "%x\n" [线程id]`将线程ID转为16进制
4.使用`jstack 进程id | grep "线程id的16进制" -A 30`打印线程的堆栈信息
5.从堆栈信息中找到是程序中的那几行代码是一直处于running状态的,从而定位问题。
6.定位问题后,将进程kill掉

五、实践

  1. 编写一个简单的springboot项目,其中编写一个死循环代码,将项目打成jar包上传服务器,并运行,然后调用接口触发死循环。

  2. 使用top命令查看进程的CPU使用率
    在这里插入图片描述
    发现有一个java项目的CPU使用率很高,接近100%,现在继续排查是什么原因导致的?

  3. 现在知道是哪个进程但是不知道哪个线程导致的,执行如下命令:

    ps -mp 82 -o THREAD,tid,time | sort -rm

    查看线程信息:
    在这里插入图片描述

  4. 拿到线程id,将线程id转为16进制,执行如下命令:

    echo ‘obase=16;104’ | printf “%x\n” 104

    在这里插入图片描述

  5. 使用jstack打印java虚拟机的堆栈信息,执行如下命令:

    jstack 82 | grep “68” -A 30

    找到处于正在运行的程序: 在这里插入图片描述

  6. 进入项目中查看,对应位置的代码:
    在这里插入图片描述

  7. 找到问题,改掉代码,并kill掉进程

    kill -9 82

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐