常用linux命令定位程序性能问题——TOP命令

一、top命令查看系统cpu使用率与负载

1.1 cpu使用率与负载之间的关系

cpu使用率代表cpu被利用的时间占比,如果一个进程占用cpu但是不使用,使用率是可能会为0的。而load则是排队使用cpu的人同时有多少。如果一个cpu同时有5个进程要使用,那么load就是5。

1.2 top命令使用

css 复制代码
top 查看系统cpu的使用状态
css 复制代码
top 之后按1 可以查看每个cpu的使用状态
css 复制代码
查看每个进程里面每个线程占用cpu的状态
top -H -p pid

cpu进程相关:

属性 含义
load average 系统负载,即任务队列的平均长度。三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值。
total 进程总数
running 正在运行的进程数
sleeping 睡眠的进程数
stopped 停止的进程数
zombie 僵尸进程数
Cpu(s):us 用户空间占用CPU百分比
Cpu(s):sy 内核空间占用CPU百分比
Cpu(s):ni 用户进程空间内改变过优先级的进程占用CPU百分比
Cpu(s):id 空闲CPU百分比
Cpu(s):wa 等待输入输出的CPU时间百分比
Cpu(s):hi 硬件CPU中断占用百分比
Cpu(s):si 软中断占用百分比
Cpu(s):st 虚拟机占用百分比

内存相关:

属性 含义
Mem:total 物理内存总量
Mem:used 使用的物理内存总量
Mem:free 空闲内存总量
Mem:buffers 用作内核缓存的内存量

交换区相关:

属性 含义
Swap:total 交换区总量
Swap:used 使用的交换区总量
Swap:free 空闲交换区总量
Swap:cached 缓冲的交换区总量,内存中的内容被换出到交换区,而后又被换入到内存,但使用过的交换区尚未被覆盖,该数值即为这些内容已存在于内存中的交换区的大小,相应的内存再次被换出时可不必再对交换区写入。

进程信息区统计信息区域的下方显示了各个进程的详细信息:

序号 列名 含义
a PID 进程id
b PPID 父进程id
c RUSER Real user name
d UID 进程所有者的用户id
e USER 进程所有者的用户名
f GROUP 进程所有者的组名
g TTY 启动进程的终端名。不是从终端启动的进程则显示为 ?
h PR 优先级
i NI nice值。负值表示高优先级,正值表示低优先级
j P 最后使用的CPU,仅在多CPU环境下有意义
k %CPU 上次更新到现在的CPU时间占用百分比
l TIME 进程使用的CPU时间总计,单位秒
m TIME+ 进程使用的CPU时间总计,单位1/100秒
n %MEM 进程使用的物理内存百分比
o VIRT 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
p SWAP 进程使用的虚拟内存中,被换出的大小,单位kb。
q RES 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
r CODE 可执行代码占用的物理内存大小,单位kb
s DATA 可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb
t SHR 共享内存大小,单位kb
u nFLT 页面错误次数
v nDRT 最后一次写入到现在,被修改过的页面数。
w S 进程状态(D=不可中断的睡眠状态,R=运行,S=睡眠,T=跟踪/停止,Z=僵尸进程)
x COMMAND 命令名/命令行
y WCHAN 若该进程在睡眠,则显示睡眠中的系统函数名
z Flags 任务标志,参考 sched.h

更改显示内容通过 f 键可以选择显示的内容。

常用top命令操作

scss 复制代码
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的进程的资源使用情况,并显式该进程启动的命令行参数

查看系统cpu核数量的命令

CPU核心通常指的就是CPU Core,意思是部分CPU处理单元。简单来说,一个CPU(中央处理单元)可能有一个或多个核心,这些核心可以同时处理不同的任务,从而提高计算机的性能和多任务处理能力。

在多核心CPU系统中,操作系统将可以同时执行更多的线程或进程,这样可以更有效地处理多任务负载。这就是为什么在解释load average时需要考虑CPU核心数量的原因。每个核心基本上可以视作一个可以独立处理任务的单元。因此,当你在评估系统负载时,一个核心的设计允许一定程度的并行处理能力。

bash 复制代码
# 总核数 = 物理CPU个数 X 每颗物理CPU的核数 
# 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数

# 查看物理CPU个数
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l

# 查看每个物理CPU中core的个数(即核数)
cat /proc/cpuinfo| grep "cpu cores"| uniq

# 查看逻辑CPU的个数
cat /proc/cpuinfo| grep "processor"| wc -l

二、如何通过top命令给出的信息来判断程序是否健康

2.1 load与cpu使用率之间的关系

cpu反应的是采样时间内cpu的使用情况,如果cpu高说明当前cpu处于忙碌状态

load表示当前系统正在使用cpu、等待使用cpu、等待io的进程数量,top中3个时间表示1分钟、5分钟、15分钟的平均值

他们的关系是如果cpu较高但是load不高,小于核数量,说明系统处于忙碌状态但是在承受范围内,并没有超过负荷如果load大于核数量说明有进程在等待使用cpu,系统处于超过负荷状态,需要排查问题,不然可能不久就会崩溃

load average的值是代表系统在最后1分钟、5分钟和15分钟内的平均进程数量,既然处于可运行状态(正在运行或者等待运行)的进程。这个数值并不直接分开每个CPU的负载,而是整个系统的负载。

在多核(CPU)系统中,load average的值可以这样解读:

  • 如果load average小于或接近CPU的核心数量,那么系统负载是在合理范围内的。
  • 如果load average等于CPU的核心数量,那么系统正好饱和,每个CPU核心都在忙碌中,没有空闲。
  • 如果load average大于CPU的核心数量,那么意味着存在过载情况,有进程需要等待CPU资源。

例如,假设一个系统有4个CPU核心,如果此时load average输出是 1.00, 2.00, 3.00,这意味着在过去的1分钟内平均有1个进程在等待或使用CPU,过去5分钟平均是2个,过去15分钟平均是3个。因为这些数值都小于4(CPU核心数),说明系统并没有过载。

这些值若是 4.00, 8.00, 12.00,那么在过去的1分钟内平均有4个进程同时运行,系统正好满载,而在过去5分钟和15分钟内,系统有明显的过载。

总之,load average提供了一个系统平均负载水平的快照,但是解释它的值时,需要考虑到CPU核心的数量。在多核心环境中,load average的数值实际上可以超过1而不一定表示系统过载,关键要看这个数值与CPU核数的关系。

2.1 load的监控标准

  • 0.7/每核:需要注意并排查原因 。 如果平均负载保持在> 0.70以上,那么应该在情况变得更糟之前进行调查。
  • 1.0/每核:不紧急,需要处理。如果平均负载保持在1.00以上,需要查找问题原因并立即解决。否则,你的服务器可能在任何时候出现性能问题。
  • 5.0/每核:紧急状态,立即处理。如果平均负载高于5.00,那么你的系统马上就要崩溃了,很有可能系统挂机或者hang死。因此需要立即处理这种情况,千万不要让你的系统负载达到5!

2.2 高load的5种可能

  1. 死循环或者不合理的大量循环操作,如果不是循环操作
  2. 也可能有大量的序列化反序列化操作,除此之外按照现代cpu的处理速度来说处理一大段代码也就一会会儿的事,基本对能力无消耗
  3. 频繁gc,比如YoungGC、FullGC、MetaspaceGC
  4. 大量线程频繁切换,这个时候cpu使用率可能不高
  5. 高磁盘io、高网络io
  6. 如果都不是的话,可能是系统资源吃紧或故障,检查磁盘使用、检查内存使用和外挂io设备状态

2.3 高cpu高load

说明系统处于超负荷状态,有2种可能:大量循环、大量序列化或者频繁gc

2.4 低cpu高load

高load低cpu大概率是io问题,也有可能是大量线程频繁切换导致。

  • 通过vmstat来查看上下文切换情况。(每秒几w次或几十w次)
  • 查看vmstat,查看procs下的b这列(不可中断睡眠),如果不为0说明存在io等待,初步判断是io问题
  • 磁盘io:检查top中表示磁盘io的wa的百分比,确认是不是磁盘io导致的
  • 网络io:对依赖方的调用任何一个出现比较高的耗时都会增加自身系统的load
    • 检查中间件mysql、redis的调用错误日志,mysql可以用show full processlist命令查看线程等待情况,把其中的语句拿出来进行优化
    • 检查监控中dubbo、http调用是否存在较高耗时
    • 多次打印jstack线程堆栈,查找java.net.SocketInputStream相关的代码
  • 资源吃紧或故障
    • 检查磁盘使用df- h
    • 检查内存使用free -m
    • 可用物理内存不足时会发生比较严重的swap,SSD或网络的故障时系统调用会发生比较严重的中断
相关推荐
Estar.Lee3 小时前
查手机号归属地免费API接口教程
android·网络·后端·网络协议·tcp/ip·oneapi
2401_857610035 小时前
SpringBoot社团管理:安全与维护
spring boot·后端·安全
凌冰_5 小时前
IDEA2023 SpringBoot整合MyBatis(三)
spring boot·后端·mybatis
码农飞飞5 小时前
深入理解Rust的模式匹配
开发语言·后端·rust·模式匹配·解构·结构体和枚举
一个小坑货5 小时前
Rust 的简介
开发语言·后端·rust
monkey_meng6 小时前
【遵守孤儿规则的External trait pattern】
开发语言·后端·rust
Estar.Lee6 小时前
时间操作[计算时间差]免费API接口教程
android·网络·后端·网络协议·tcp/ip
新知图书7 小时前
Rust编程与项目实战-模块std::thread(之一)
开发语言·后端·rust
盛夏绽放7 小时前
Node.js 和 Socket.IO 实现实时通信
前端·后端·websocket·node.js
Ares-Wang7 小时前
Asp.net Core Hosted Service(托管服务) Timer (定时任务)
后端·asp.net