• TOP命令详解


    TOP命令详解

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

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

    参数解释:

    • -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   // 显示某个进程下所有线程的资源占用情况
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    一、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
    • 2
    • 3
    • 4
    • 5
    • 6

    五、实践

    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

  • 相关阅读:
    P1347 排序(拓扑 + spfa判断环 or 拓扑[内判断环])
    PHP毕业设计项目作品源码选题(10)校园新生自助报到系统毕业设计毕设作品开题报告
    详解 Wilkinson 功分器
    Vue学习之--------路由的query、params参数、路由命名(3)(2022/9/5)
    js网络请求---fetch和XMLHttpRequest的用法
    andriod studio 手机模拟器中的文件导出方法
    Profiler内存泄露实际案例分析
    第六章 继承
    驱动开发2
    LeetCode.111. 二叉树的最小深度
  • 原文地址:https://blog.csdn.net/Linging_24/article/details/126436563