top cpu 进程状态 VIRT RES

[root@master-1] ~$ top
top - 09:57:41 up  7:49,  2 users,  load average: 15.03, 14.70, 14.30
Tasks: 161 total,   6 running, 138 sleeping,   0 stopped,  17 zombie
%Cpu(s):  3.1 us, 53.1 sy,  0.0 ni, 43.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  7493208 total,  3311120 free,   953128 used,  3228960 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  5216800 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                    
30821 root      20   0  159932   2208   1496 R   6.2  0.0   0:00.01 top                                                                        
    1 root      20   0  128300   6860   4176 D   0.0  0.1   0:43.39 systemd                                                                    
    2 root      20   0       0      0      0 S   0.0  0.0   0:00.01 kthreadd                                                                   
    3 root      20   0       0      0      0 S   0.0  0.0   0:18.12 ksoftirqd/0                                                                
    5 root       0 -20       0      0      0 S   0.0  0.0   0:00.00 kworker/0:0H                                                               
    7 root      rt   0       0      0      0 S   0.0  0.0   3:30.43 migration/0                                                                
    8 root      20   0       0      0      0 S   0.0  0.0   0:00.00 rcu_bh                                                                     
    9 root      20   0       0      0      0 S   0.0  0.0   0:31.71 rcu_sched                                                                  
   10 root       0 -20       0      0      0 S   0.0  0.0   0:00.00 lru-add-drain  

                                                           

常用操作


P:cpu排序

M:内存排序

c:显示完整命令

1:top默认显示的所有CPU的平均值,这个时候只需要按下数字1,就可以切换到每个CPU的使用率了。

 

1、只查看某一个进程的top参数:

  top -p pid (pid可以通过pidof命令获取,如pidof falcon-agent ,注意java进程的pid此命令无法获取)

 

2、中括号表示这个进程不是使用命令行启动的。这种进程一般是内核进程

3、关于command的数字的解释

command中k开头的这些由Linux内核创建的工作线程的命名规则是这样的:

kworker/cpu_id:thread_id 。也就是说第一个数字是cpu编号,第二个数字是线程编号或者work_pool工人集合中某个工人的序号ID

u:是unbound的缩写

不带u的就是绑定特定cpu,带着u代表没有绑定特定的CPU

H表示该线程的nice小于0,说明它的优先级很高,所以加了H

https://www.cnblogs.com/embedded-linux/p/8538569.html

关于线程编号的问题,与linux内核的工作队列workqueue有关系

在多核环境里,我们能见到的,CPU使用率的问题,大多是每个CPU的使用率都比较高。进程调度算法的一个最主要目标,就是保证不会有有的人撑死,有的人饿死的情况发生。能影响这种“公平性”的因素有两个,一个是优先级(priority),另外一个是相关性(affinity)。优先级处理的是进程之间,哪个比较重要的问题;相关性处理的是进程需要某一个CPU专门负责的问题。

相关性会引起“闲里偷忙”这种问题是显而易见的。如果一个进程被绑定到某一个CPU,那么如果这个进程持续的做计算,势必会让这一个CPU占用率变高。当前这个问题属于这一类。至于优先级和这类问题的关联,不是那么明显。优先级在一些特殊的状况下,会制造类似的麻烦,有机会我会借助例子来分析。

工作队列

相信观察仔细的同学,会发现第一张图里,kworker进程名字后边跟了24:2这样的标识。这个和大多数其他进程是不一样的。我们先从这两个数字背后的机制,工作队列说起。

关于工作队列(work queue),这边有五个核心的概念,分别是工作(work,也就是需要做的事情,分装一个函数),工作池(work pool,工作需要一个一个处理,这是一个工作的集合),工人(worker,实现为内核进程),工人小组(worker pool,工人小团队)以及第五个概念,中介。中介是把工作队列和工人小组联系起来的纽带。工作队列这个机制,是为了保证,每一个work,从被放在工作池里,然后经过中介的手,分配给某一个工人小组的某一个工人去处理,这一切都能高效有序的进行。

对每个CPU,系统会创建两个的工作小组,普通优先级组,和高优先级组。系统会根据工作多少,动态管理每个工人小组里,工人的数量。下边是从网上拿的一张图,这张图对应一个CPU的(普通优先级在上、高优先级在下)两个工作小组。我们可以看到,每个worker被实现为一个kworker进程。而kworker后边的两个数字,大家应该可以猜到,第一个代表的是CPU的编号,第二个代表着一个工人在工人小组里的编号。当前这个问题中,kworker是第24个CPU的第2个worker。这也是为什么,在第二张图里,第24个CPU的系统使用率高的。

1d8f5ffe49d76f172b36d0c30dfcb5290322ca88

备注:关于工作队列,我这里其实省略了很多细节,而且work pool这个概念是不存在的,它原本是work queue,为了区分这个概念,和工作队列这个机制本身,我稍微修改了一下。

https://yq.aliyun.com/articles/504369?spm=a2c4e.11155435.0.0.28b06a95Zkd8RM

5、想以进程名来查看的话,比方说我想查进程名称是python的,下面的命令会显示所以command为python的进程的进程号,并换行显示。然后用top -p pid来看

pgrep python

想查进程名是以k开头的内核进程,如下。注意top -p进程号的时候,最多指定20个进程号

top -p `pgrep ^k |head -n 20| tr "\\n" "," | sed 's/,$//'` 


参数说明


us:user CPU time, 用户空间占用CPU百分比。注意,它不包括下面的 nice 时间,但包括了 guest 时间。为啥不包括见ni的解释。
sy:system CPU time  内核空间占用CPU百分比

用户空间和内核空间是什么?

Linux按照特权等级,把进程的运行空间分为内核空间和用户空间,分别对应着下图中,CPU特权等级的Ring 0和Ring 3。

  • 内核空间(Ring 0)具有最高权限,可以直接访问所有资源;

  • 用户空间(Ring 3)只能访问受限资源,不能直接访问内存等硬件设备,必须通过系统调用陷入到内核中,才能访问这些特权资源。

换个角度看,也就是说,进程既可以在用户空间运行,又可以在内核空间中运行。进程在用户空间运行时,被称为进程的用户态,而陷入内核空间的时候,被称为进程的内核态。

从用户态到内核态的转变,需要通过系统调用来完成。比如,当我们查看文件内容时,就需要多次系统调用来完成:首先调用open()打开文件,然后调用read()读取文件内容,并调用write()将内容写到标准输出,最后再调用close() 关闭文件。

hi:hardware irq(Interrupt Request),硬中断消耗cpu时间
si:software irq(Interrupt Request)软中断消耗cpu时间

ni: nice CPU time,nice值代表一个进程使用Cpu资源的优先程度。nice 可取值范围是 -20 到 19。nice值越高,优先级就越低。ni这个指标,统计的是系统中,所有nice值大于0的用户空间进程的Cpu的使用率。也就是nice 值被调整为 1-19 之间的进程 CPU使用率之和。

一般情况下进程默认的nice值是0,而当有些进程需要更高的执行优先级的时候,我们会减小这些进程的nice值。当然有一些并不需要在高优先级运行的进程,例如我们跑编译程序gcc,去编译一个内核,这个操作预计会花几个小时,那么我们可以增加这个gcc进程的nice值。

linux会把真正的用户模式Cpu使用率拆分成两部分显示,nice值大于0的显示为ni(所以也叫低优先级用户态 CPU 时间),小于等于0的显示为us。

nice值是什么

每个linux进程都有个优先级,优先级高的进程有优先执行的权利,这个叫做pr(进程创建时根据进程所需的资源多少,将要运行的时间长短,进程是什么类型,如io/cpu,前台/后台,核心/用户,来确定的一个静态优先级)。

进程除了优先级外,还有个优先级的修正值,这就是ni(nice),这个是动态的优先级。

当进程使用cpu超过一定时长,或者进程等待一定时长时等等,此时系统会自动分配一个修正值,来改变进程的优先级,除了系统自动分配之外,也可以在手动通过
renice +19 -p $pid命令来指定。 即比如你原先的优先级pr是20,然后修正值ni为-2,那么你最后的进程优先级为18。从20到18,这个进程的优先级被提高了。ni表示的就是被提高优先级的这些用户空间进程(注意有个空户空间)所占用的cpu百分比。那么nice是一个进程的优先级修正值,为什么会占用cpu时间呢?ni是指用做nice加权的进程使用的用户态cpu时间比,我的理解就是一个进程的所谓修正值就意味着多分配一些cpu时间给这个进程的用户态,这个中间所多分配的cpu时间就是我们这里的ni。(这个理解没啥把握,如果有错误麻烦帮忙指出下)

为什么要起个这么个名字?

一个人越nice,就越喜欢帮助人,比方坐公交车让个座之类的。

wa:iowait,CPU等待io的时间

就是说前提是要进行IO操作,在进行IO操作的时候,CPU等待时间。比如上面那个程序,最后一步,从系统空间到dst硬盘空间的时候,如果程序是阻塞的,那么这个时候cpu就要等待数据写入磁盘才能完成写操作了。所以这个时候cpu等待的时间就是wa。所以如果一台机器看到wa特别高,那么一般说明是磁盘IO出现问题,可以使用iostat等命令继续进行详细分析。

st: steal time,只对虚拟机有效,当系统运行在虚拟机中的时候,被其他虚拟机占用的 CPU 时间。

id: idle,空闲时间,注意,它不包括等待 I/O 的时间(iowait)。

guest:通过虚拟化运行其他操作系统的时间,也就是运行虚拟机的 CPU 时间。

gnice:以低优先级运行虚拟机的时间。

switches: 上下文切换,意思是 CPU 从一个进程或线程切换到另一个进程或线程

第三行的 cpu指标相加应该是100%。
即:总得cpu使用率 =%usr + %nice + %sys+ %iowait+ %irq + %soft + %steal  + %idle

而我们通常所说的CPU使用率,就是除了空闲时间(idle+iowait)外的其他时间占总CPU时间的百分比

 

上面这个计算方式是不具备参考意义的,因为总CPU时间是机器开机以来的,事实上,为了计算CPU使用率,性能工具都会取间隔一段时间(比如5秒)的两次值,做差后,再计算出这段时间内的平均CPU使用率

这个公式,就是我们用各种性能工具所看到的 CPU 使用率的实际计算方法。

Linux 也给每个进程提供了运行情况的统计信息,也就是 /proc/[pid]/stat。不过,这个文件包含的数据就比较丰富了,总共有 52 列的数据。

不过需要注意的是,性能分析工具给出的都是间隔一段时间的平均CPU使用率,所以要注意间隔时间的设置,特别是多个工具对比分析时,需要保证它们的间隔时间是相同的。

比如,对比一下top和ps这两个工具报告的CPU使用率,默认的结果可能不一样,因为top默认使用3秒时间间隔,而ps使用的却是进程的整个生命周期。

 

进程相关


PR:进程的优先级别,由 OS 内核动态调整,用户不能改变,越小优先级越高。取值0-139

NI:nice值。nice值是每个进程的一个属性。它不是进程的优先级,而是一个能影响优先级的数字。

nice是-20~~19之间的整数,默认取中间值0。

用户可以通过renice命令自行调整,负值表示高优先级,正值表示低优先级

ni是nice的意思,nice是什么呢,每个linux进程都有个优先级,优先级高的进程有优先执行的权利,这个叫做pri。进程除了优先级外,还有个优先级的修正值。即比如你原先的优先级是20,然后修正值为-2,那么你最后的进程优先级为18。这个修正值就是nice,这个值为负值且越小 就说明进程的优先级会被提高的越多。

 

静态优先级:(定义在进程描述符中的:static_prio)

动态优先级:(定义在进程描述符中的:prio)

实时优先级:(定义在进程描述符中的:rt_priority)

 

静态优先级:

    定义:他不随时间改变,内核不会主动修改它,只能通过系统调用nice去修改static_prio

动态优先级:

   定义:调度程序通过或减少进程静态优先级来奖励IO消耗型进程或惩罚CPU消耗进程,调整后的优先级为动态优先级(prio)

实时优先级:

  实时优先级只对实时进程有效

内存相关

VIRT:进程占用的虚拟内存,只要是进程申请过的内存,即便还没有真正分配物理内存,也会计算在内。

虚拟内存,包括了进程代码段、数据段、共享内存、已经申请的堆内存和已经换出的内存等。这里要注意,已经申请的内存,即使还没有分配物理内存,也算作虚拟内存。

RES:常驻内存的大小,也就是进程实际使用的物理内存大小,但不包括Swap和共享内存。

常驻内存一般会换算成占系统总内存的百分比,也就是进程的内存使用率

SHR:进程使用的共享内存,比如与其他进程共同使用的共享内存、加载的动态链接库以及程序的代码段等。

S:进程的状态。S表示休眠sleep,R表示正在运行running,Z表示僵死状态zombie,N表示该进程优先值为负数

%CPU:进程占用CPU的使用率,

%MEM:进程使用的物理内存与总内存的百分比

使用top 查看内存需要注意:

  • 虚拟内存通常并不会全部分配给物理内存
  • 共享内存 SHR 并不一定是共享,例如程序的代码段、非共享的动态链接库,也都算在 SHR 里。当然,SHR 也包括了进程间真正共享的内存。所以在计算多个进程的内存使用时,不要把所有进程的 SHR 直接相加得出结果。

TIME+:该进程启动后占用的总的CPU时间,即占用CPU使用时间的累加值。

意思就是你如果有多个CPU,或者是多核CPU的话,那么,进程占用多个cpu的时间是累加起来的。单位是1/100秒。比如3:30.43,从右到左分别是百分之一秒,十分之一秒,秒,十秒,分钟,拿这个说就是3分钟,30秒,0秒,十分之4秒,百分之3秒,是按位来计算的

 

进程四要素

  • 有一段程序供其执行,就好一个演员要有个剧本一样。当然多个进程可以共用同一个剧本。
  • 有起码的私有财产,这就是进程专用的系统(内核)空间堆栈。
  • 有户口,这就是内核空间中的进程控制块task_struct结构。有了这个户口,内核才能看到它,对它实施调度。同时这个结构又是进程的财产登记卡,记录着进程所占用的各项资源。
  • 有独立的用户空间,这就是mm_struct结构。该结构登记在进程的财产登记卡task_struct结构中,字段名称为mm。

进程状态


R:running or runnable (on run queue):表示进程在CPU的就绪队列中,正在运行或者正在等待运行,这些进程占用或等待cpu资源。

TASK_RUNNING 状态并不是表示一个进程正在运行,或者是这个进程就是“当前进程”,而是表示这个进程可被调度执行而成为当前进程,是进程表达了希望被调度运行的意愿。当进程处于此状态时,表示进程已经准备就绪或者可以被执行了,内核会将该进程的task_struct结构通过其队列头run_list链入一个“可执行队列”,至于最终调度运行谁,内核会根据调度策略从“可执行队列”中挑选一个进程来调度运行。

S :interruptible sleep (waiting for an event to complete),可中断的睡眠状态,表示进程由于等待某个进程而被系统挂起。当进程等待的事件发生时,它会被唤醒并进入 R 状态。
 

处在这种睡眠状态的进程是可以通过给它发信号来唤醒的,比如发HUP信号给nginx的master进程可以让nginx重新加载配置文件而不需要重新启动nginx进程。

通过ps命令我们会看到,一般情况下,进程列表中的绝大多数进程都处于s状态。毕竟CPU就这么一两个,进程动辄几十上百个,如果不是绝大多数进程都在睡眠,CPU又怎么响应得过来。

D :uninterruptible sleep (usually IO),不可中断的睡眠状态,一般表示进程正在跟硬件交互,并且过程不允许被其他进程或中断打断。会导致平均负载升高。处于此状态的进程处于内核态,并且不接收任何信号。

为什么是简写是D,在内核源码 fs/proc/array.c 里,其文字定义为“ "D (disk sleep)", /* 2 */ ”

为了保护进程数据和硬件的一致性,系统不允许其他进程或中断打断这个进程。进程长时间处于不可中断状态,通常表示系统有 I/O 性能问题。

处于uninterruptible sleep状态的进程通常是在等待IO,比如磁盘IO,网络IO,其他外设IO,如果进程正在等待的IO在较长的时间内都没有响应,那么就很会不幸地被 ps看到了,同时也就意味着很有可能有IO出了问题,可能是外设本身出了故障,也可能是比如挂载的远程文件系统已经不可访问了,我这里遇到的问题就是由 down掉的NFS服务器引起的。

正是因为得不到IO的相应,进程才进入了uninterruptible sleep状态,所以要想使进程从uninterruptible sleep状态恢复,就得使进程等待的IO恢复,比如如果是因为从远程挂载的NFS卷不可访问导致进程进入uninterruptible sleep状态的,那么可以通过恢复该NFS卷的连接来使进程的IO请求得到满足,除此之外,要想干掉处在D状态进程就只能重启整个Linux系统了。

这种状态的进程还处于CPU 的run_queue 里,此时cpu 一般Load 很高。

T (stopped by job control signal),暂停状态或跟踪状态。

向进程发送一个SIGSTOP信号,它就会因响应该信号而进入TASK_STOPPED状态(除非该进程本身处于TASK_UNINTERRUPTIBLE状态而不响应信号)。

对于进程本身来说,TASK_STOPPED和TASK_TRACED状态很类似,都是表示进程暂停下来。
而TASK_TRACED状态相当于在TASK_STOPPED之上多了一层保护,处于TASK_TRACED状态的进程不能响应SIGCONT信号而被唤醒。只能等到调试进程退出,被调试的进程才能恢复TASK_RUNNING状态。

Z (zombie僵尸),僵尸状态,即进程实际上已经结束了,但父进程还没有回收它的资源(如:进程的描述符、PID等)

僵尸进程,是多进程应用很容易碰到的问题。正常情况下,当-一个进程创建了子进程后,它应该通过系统调用wait()或者waitpid()等待子进程结束,回收子进程的资源;而子进程在结束时,会向它的父进程发送SIGCHLD信号,所以,父进程还可以注册SIGCHL .D信号的处理函数,异步回收资源。

如果父进程没这么做,或是子进程执行太快,父进程还没来得及处理子进程状态,子进程就已经,提前退出,那这时的子进程就会变成僵尸进程。换句话说,父亲应该一直对儿子负责,善始善终,如果不作为或者跟不上,都会导致“问题少年”的出现。

通常,僵尸进程持续的时间都比较短,在父进程回收它的资源后就会消亡;或者在父进程退出后,由init进程回收后也会消亡。

一旦父进程没有处理子进程的终止,还一直保持运行状态,那么子进程就会一直处于僵尸状态。大量的僵尸进程会用尽 PID 进程号,导致新进程不能创建,所以这种情况一定要避免。

当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。如果父进程先退出 ,子进程被init接管,子进程退出后init会回收其占用的相关资源

进程在退出的过程中,处于TASK_DEAD状态。

在这个退出过程中,进程占有的所有资源将被回收,除了task_struct结构(task_struct结构会占用内存以及少数资源)以外。于是进程就只剩下task_struct这么个空壳,故称为僵尸。

之所以保留task_struct,是因为task_struct里面保存了进程的退出码、以及一些统计信息。而其父进程很可能会关心这些信息。比如在shell中,$?变量就保存了最后一个退出的前台进程的退出码,而这个退出码往往被作为if语句的判断条件。

进程已经退出,但它的父进程还没有回收子进程占用的资源。短暂的僵尸状态我们通过不必理会,但进程长时间处于僵尸状态,就应该注意了,可能有应用程序没有正常处理子进程的退出。

如果这样的进程很多,也会占用很多系统资源(内存、系统表)

X (exit),退出状态或者死亡状态,进程已经死亡即将被销毁。

意味着接下来的代码立即就会将该进程彻底释放。所以EXIT_DEAD状态是非常短暂的,几乎不可能通过ps命令捕捉到。

参考

https://blog.csdn.net/nilxin/article/details/7437671

https://www.cnblogs.com/yjf512/p/3383915.html

https://www.cnblogs.com/liyongjian5179/p/10167447.html

 

linux下获取占用CPU资源最多的10个进程

ps aux|head -1;ps aux|grep -v PID|sort -rn -k +3|head

linux下获取占用内存资源最多的10个进程

ps aux|head -1;ps aux|grep -v PID|sort -rn -k +4|head

 

CPU利用率和cpu负载

CPU负载,是指CPU正在处理以及需要等待CPU处理的任务数,是对CPU使用队列长度的统计信息。通常zabbix等监控系统中的CPU load的监控指标,量化的就是每个核的负载情况。

CPU利用率cpu.util,表明了一段时间内CPU被占用的情况。他是这样计算出来的:执行用户态+系统态的时间除以统计时间。CPU利用率里面包含系统利用率和用户利用率,也就是cpu.util=cpu.sys+cpu.us 通常这个比例维持在7:3左右。比如A进程占用10ms,然后B进程占用30ms,然后空闲60ms,再又是A进程占10ms,B进程占30ms,空闲60ms; 如果在一段时间内都是如此,那么这段时间内的占用率为40%。使用率越高,说明你的机器在这个时间上运行了很多程序,反之较少。

CPU利用率显示的是程序在运行期间实时占用的CPU百分比

而CPU负载显示的是一段时间内正在使用和等待使用CPU的平均任务数。

ksoftirqd/0是干什么的?

您的计算机通过IRQ(中断请求)与连接到它的设备进行通信。当来自设备的中断时,操作系统会暂停它正在执行的操作并开始寻址该中断。

在某些情况下,IRQ一个接一个地非常快,操作系统无法在另一个到达之前完成一个服务。当高速网卡在短时间内收到大量数据包时,就会发生这种情况。

因为操作系统在到达时无法处理IRQ(因为它们一个接一个地到达得太快),操作系统会将它们排队等待稍后由名为ksoftirqd的特殊内部进程处理。

如果ksoftirqd占用的CPU时间超过一小部分,则表示机器处于严重的中断负载下。

作者:,Lucian Adrian Grijincu

CPU异常排查思路

1、top查不到是哪个进程或者线程消耗了cpu

2、查看监控数据,检查CPU是从什么时候开始出现使用率100%。
现象是不是从某一刻起,CPU突然100%,而且一直没有下降。

3、查看系统命令在最近时间是否有修改过。
stat /usr/bin/top 
stat /bin/ps 
查看命令的 Change时间,是否是和CPU使用率出现100%的时间点吻合。

 

4、rpm 验证一下命令是否有被修改。
正常情况应该是查看不到修改信息的
rpm -Vf /bin/ps
rpm -Vf /usr/bin/top

5、观察服务器对外的网络连接情况。
iftop -i eth1 -n -P
是否对外连接一些异常的地址,例如 crypto-pool.fr 之类的异常域名地址

image

总结:符合以上几个特征,基本可以判定,服务器系统已经中招,中毒了。

尽快备份一下服务器的数据,考虑重装系统,然后加强服务器系统的安全防护。

展开阅读全文

没有更多推荐了,返回首页