Linux中top命令输出详解
前言
Linux下的top命令我相信大家都用过,自从我接触Linux以来就一直用top查看进程的CPU和MEM排行榜。但是top命令的其他输出结果我都没有了解,这些指标都代表什么呢,什么情况下需要关注呢?以及top命令输出结果的来源数据是什么呢,又是怎么一个计算原理呢?
演示环境
#uname-a LinuxVM_1_11_centos3.10.0-693.el7.x86_64#1SMPTueAug2221:09:27UTC2017x86_64x86_64x86_64GNU/Linux
top命令
top命令是Linux下常用的性能分析工具,能够实时(默认是3s刷新一次)的显示系统的资源使用情况,以及各种进程的资源使用情况,类似于Windows的任务管理器。
top-11:00:54up54days,23:35,6users,loadaverage:16.32,18.75,21.04 Tasks:209total,3running,205sleeping,0stopped,1zombie %Cpu(s):29.7us,18.9sy,0.0ni,49.3id,1.7wa,0.0hi,0.4si,0.0st KiBMem:32781216total,1506220free,6525496used,24749500buff/cache KiBSwap:0total,0free,0used.25607592availMem PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND root20015.6g4616764704R198.01.411:15.26python root20097255962400284672R113.00.77:48.49python root20068780281431964720S82.40.41:35.03python
第一行数据相当于uptime命令输出。11:00:54是当前时间,up54days,23:55是系统已经运行的时间,6users表示当前有6个用户在登录,loadaverage:16.32,18.75,21.04分别表示系统一分钟平均负载,5分钟平均负载,15分钟平均负载。
平均负载
平均负载表示的平均活跃进程数,包括正在running的进程数,准备running(就绪态)的进程数,和处于不可中断睡眠状态的进程数。如果平均负载数刚好等于CPU核数,那证明每个核都能得到很好的利用,如果平均负载数大于核数证明系统处于过载的状态,通常认为是超过核数的70%认为是严重过载,需要关注。还需结合1分钟平均负载,5分钟平均负载,15分钟平均负载看负载的趋势,如果1分钟负载比较高,5分钟和15分钟的平均负载都比较低,则说明是瞬间升高,需要观察。如果三个值都很高则需要关注下是否某个进程在疯狂消耗CPU或者有频繁的IO操作,也有可能是系统运行的进程太多,频繁的进程切换导致。比如说上面的演示环境是一台8核的centos机器,证明系统是长期处于过载状态在运行。
Tasks:214total, 4running,209sleeping, 0stopped, 1zombie
第二行的Tasks信息展示的系统运行的整体进程数量和状态信息。214total表示系统现在一共有214个用户进程,4running表示4个进程正在处于running状态,209sleeping表示209个进程正处于sleeping状态,0stopped表示0个进程正处于stopped状态,1zombie表示有1个僵尸进程。
僵尸进程
子进程结束时父进程没有调用wait()/waitpid()等待子进程结束,那么就会产生僵尸进程。原因是子进程结束时并没有真正退出,而是留下一个僵尸进程的数据结构在系统进程表中,等待父进程清理,如果父进程已经退出则会由init进程接替父进程进行处理(收尸)。由此可见,如果父进程不作为并且又不退出,就会有大量的僵尸进程,每个僵尸进程会占用进程表的一个位置(slot),如果僵尸进程太多会导致系统无法创建新的进程,因为进程表的容量是有限的。所以当zombie这个指标太大时需要引起我们的注意。下面的进程详细信息中的S列就代表进程的运行状态,Z表示该进程是僵尸进程。
消灭僵尸进程的方法:
1.找到僵尸进程的父进程pid(pstress可以显示进程父子关系),kill-9pid,父进程退出后init自动会清理僵尸进程。(需要注意的是kill-9并不能杀死僵尸进程)
2.重启系统。
%Cpu(s):31.9us,30.3sy,0.0ni,37.0id,0.0wa,0.0hi,0.8si,0.0st
第三行的%Cpu(s)表示的是总体CPU使用情况。
- ususer表示用户态的CPU时间比例
- sysystem表示内核态的CPU时间比例
- ninice表示运行低优先级进程的CPU时间比例
- ididle表示空闲CPU时间比例
- waiowait表示处于IO等待的CPU时间比例
- hihardinterrupt表示处理硬中断的CPU时间比例
- sisoftinterrupt表示处理软中断的CPU时间比例
- ststeal表示当前系统运行在虚拟机中的时候,被其他虚拟机占用的CPU时间比例。
所以整体的CPU使用率=1-id。当us很高时,证明CPU时间主要消耗在用户代码,需要优化用户代码。sy很高时,说明CPU时间都消耗在内核,要么是频繁的系统调用,要么是频繁的CPU切换(进程切换/线程切换)。wa很高时,说明有进程在进程频繁的IO操作,有可能是磁盘IO,也有可能是网络IO。si很高时,说明CPU时间消耗在处理软中断,网络收发包会触发系统软中断,所以大量的网络小包会导致软中断的频繁触发,典型的SYNFloor会导致si很高。
KiBMem:32781216total,663440free,7354900used,24762876buff/cache KiBSwap:0total,0free,0used.24771700availMem
第4,5行显示的是系统内存使用情况。单位是KiB。totol表示总内存,free表示没使用过的内容,used是已经使用的内存。buff表示用于读写磁盘缓存的内存,cache表示用于读写文件缓存的内存。avail表示可用的应用内存。
Swap原理是把一块磁盘空间或者一个本地文件当成内存来使用。Swaptotal表示能用的swap总量,swapfree表示剩余,used表示已经使用的。这三个值都为0表示系统关闭了swap功能,由于演示环境是一台虚拟机,虚拟机一般都关闭swap功能。
第6行开始往后表示的是具体的每个进程状态:
PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND
- PID进程ID
- USER进程所有者的用户名,例如root
- PR进程调度优先级
- NI进程nice值(优先级),越小的值代表越高的优先级
- VIRT进程使用的虚拟内存
- RES进程使用的物理内存(不包括共享内存)
- SHR进程使用的共享内存
- CPU进程使用的CPU占比
- MEM进程使用的内存占比
- TIME进程启动后到现在所用的全部CPU时间
- COMMAND进程的启动命令(默认只显示二进制,top-c能够显示命令行和启动参数)
计算原理
在介绍top命令的各项指标计算原理之前,有必要先介绍下Linux下的proc文件系统,因为top命令的各项数据来源于proc文件系统。proc文件系统是一个虚拟的文件系统,是Linux内核和用户的一种通信方式,Linux内核会通过proc文件系统告诉用户现在内核的状态信息,用户也可以通过写proc的方式设置内核的一些行为。与普通文件不同的是,这些proc文件是动态创建的,也是动态修改的,因为内核的状态时刻都在变化。
top显示的CPU指标都是来源于/proc/stat文件信息:
#cat/proc/stat cpu115182938020277540128095190900452421051740010957596000 cpu0143829475391867658924235696976516851401475030000 cpu1144407338196667616825236756510396911001392212000 cpu2144531920228767567520238021699271317501363460000 cpu3143288938236667474485239715220222373901356698000 cpu4143975390315967394206239494900194842401343261000 cpu5144130685221267538520239431294178075601349882000 cpu6144009592217567536945239683876166820301340087000 cpu7143656038219367340668240204045157981601336963000
第一行代表的总的CPU信息,后面的是一个CPU的详细信息。
但是这些具体的后面的列都是什么信息呢,我们可以通过manproc找到答案:
user(1)Timespentinusermode. nice(2)Timespentinusermodewithlowpriority(nice). system(3)Timespentinsystemmode. idle(4)Timespentintheidletask.ThisvalueshouldbeUSER_HZtimesthesecondentryinthe /proc/uptimepseudo-file. iowait(sinceLinux2.5.41) (5)TimewaitingforI/Otocomplete. irq(sinceLinux2.6.0-test4) (6)Timeservicinginterrupts. softirq(sinceLinux2.6.0-test4) (7)Timeservicingsoftirqs. steal(sinceLinux2.6.11) (8)Stolentime,whichisthetimespentinotheroperatingsystemswhenrunninginavirtual‐ izedenvironment guest(sinceLinux2.6.24) (9)TimespentrunningavirtualCPUforguestoperatingsystemsunderthecontroloftheLinuxkernel. guest_nice(sinceLinux2.6.33) (10)Timespentrunninganicedguest(virtualCPUforguestoperatingsystemsunderthecon‐ troloftheLinuxkernel).
也就是说从第二列开始往后分别是user,nice,system,idle,iowait,irq(硬中断),softirq(软中断),steal,guest,guest_nice的CPU时间,单位通常是10ms。那么top里面的比例又是怎么算出的呢?
由于CPU时间是一个累加值,所以我们要求一个时间段差值来反映当前的CPU情况,top默认是3s。例如现在取一个user值user1,和当前的一个总量的CPU时间total1
其中total等于上面各项相加,也就是total=user+nice+system+idle+iowait+irq+softirq+steal+guest+guest_nice。3秒后再去一个user值user2和一个总量total2。
那么这3秒钟的user平均cpu占比就等于((user2-user1)/(total2-total1))/3*100%。另外每个具体的CPU计算方式同理。
top内存相关的指标直接读取/proc/meminfo文件的对应字段:
#cat/proc/meminfo MemTotal:32781216kB MemFree:1043556kB MemAvailable:25108920kB Buffers:427516kB Cached:22084612kB SwapCached:0kB Active:18640888kB Inactive:10534920kB Active(anon):6664480kB Inactive(anon):412kB Active(file):11976408kB Inactive(file):10534508kB Unevictable:4kB Mlocked:4kB SwapTotal:0kB SwapFree:0kB Dirty:1092kB Writeback:0kB AnonPages:6663764kB Mapped:347808kB Shmem:1212kB Slab:2201292kB SReclaimable:1957344kB SUnreclaim:243948kB KernelStack:73392kB PageTables:57300kB NFS_Unstable:0kB Bounce:0kB WritebackTmp:0kB CommitLimit:16390608kB Committed_AS:42170784kB VmallocTotal:34359738367kB VmallocUsed:61924kB VmallocChunk:34359625048kB HardwareCorrupted:0kB AnonHugePages:364544kB HugePages_Total:0 HugePages_Free:0 HugePages_Rsvd:0 HugePages_Surp:0 Hugepagesize:2048kB DirectMap4k:376680kB DirectMap2M:26886144kB DirectMap1G:8388608kB
其中total对应于MemTotal,free对应于MemFree,avail对应于MemAailable。
总结
文章从top命令的输出结果开始,说明哪些指标的异常值需要我们关注,最后介绍了top命令的cpu计算原理和mem的数据来源。