CPU消耗
load average: load average后面的三个数分别是1分钟、5分钟、15分钟的负载情况。
load average数据是每隔5秒钟检查一次活跃的进程数,然后按特定算法计算出的数值。如果这个数除以逻辑CPU的数量,结果高于1的时候就表明系统在超负荷运转了;
cpu利用率总和=红框内所有项相加,主要看us 和sy;(看第一处)
us:用户态进程所消耗的CPU;
sy:系统内核调用所消耗的CPU;
ni:优先级高的系统进程切换所消耗的cup;(改变过优先级的进程占用CPU的百分比)
id:空闲进程的CPU所占百分比;
wa:IO等待占用CPU的百分比;
hi:硬中断(Hardware IRQ)占用CPU的百分比;()
si:软中断(Software Interrupts)占用CPU的百分比;()
中断:CPU切换或进程切换,切换时产生上下文;
上下文:CPU切换的时候保留切换前进程的状态,以便进程切换回来的时候,原进程继续执行;
mem:物理内存
swap:虚拟内存,从磁盘上一处不用地方当成内存使用,当内存 不足时会调用虚拟内存,但是特别慢,用到虚拟内存并且动态看时,虚拟内存一直增加,一般说明出问题了;
buffers:把文件缓冲起来,避免频 繁写磁盘
cached:缓存,把磁盘的数据缓存起来,避免频繁读磁盘
free:剩余内存不会为0,因为有内存剩余保护量;
VIRT:当前进程所占用的内存,包括物理内存和虚拟内存(了解他,但不要看他)
RES: 真正的物理内存(不带单位的默认是k)
SHR:共享内存
交换区的使用有很多命令 ,自己尝试一下;
注意:图1第二处有关CPU,不仅要看所有CPU使用的平均值,还应关注每个CPU的使用情况,CPU要使用的平稳且平均;例如8颗CPU,观察到只有两颗被利用,其余6颗全部空转,说明另外6颗完全没有发挥作用;
问题a:
8核cup,cup利用率400%正常吗?(看第二处、第三处)
第二处cpu(s)指的是多核cpu的平均使用率,第三处CPU指的是多核CPU使用率的总和,所以看第三处,8核400%正常;
如果你的进程利用了多个cpu,那么top命令显示的是多个cpu占用率的总和。
所以top命令下查看到的cpu利用率是可能超过100%的。
问题b:CPUs展开会有cup0,cpu1,cpu2...,为什么cpu0比较重要?(看第二处)
按“1”切换
类似于进程下的线程,一个进程下有多个线程,多个线程中有一个主线程(或者守护线程),同步检测,实时去看其他线程的状态,
对于CPU,他有一个主CPU,决定其他CPU的分发状况,相当于其他CPU的大脑,控制其他CPU怎么轮洵,怎么切片;
CPU状态
tasks:总进程;
running:正在运行的进程;
sleeping:休眠-不消耗CPU
stopped:停止
zombie:僵尸进程,进程意外停止又不退出;
在CPU中来回切换的几种状态:
running:
中断可恢复:
中断不可恢复:
负载=正在等待磁盘IO的进程+正在运行的进程 ;
总结1:
CPU中的进程数和等待读磁盘IO的进程数是时刻变化的,大量的数据库等待操作,会造成负载很高,cpu利用率很低;
总结2:
一个查询操作造成应用的CPU负载很高,可能的原因是:开发从数据库取回数据之后在代码里进行了逻辑计算的处理,因为数据拿回来是在内存里的,也就是在内存里做了处理,所以CPU利用率很高;解决方法,把判断处理的逻辑放到数据库里操作;
反之如果数据库的CPU负载很高,可以把在数据库里处理的计算、业务和逻辑放到代码里处理;
一切数据库问题皆IO问题;
总结3:
看一个系统的CPU利用率高低要和负载以及系统类型结合起来,不应独立去看;
计算密集型系统:CPU利用率高很正常,但是同时CPU负载也高就有问题;
CPU利用率很低,负载很高更不正常,说明大量的在等待磁盘或外部数据返回;
IO密集型系统:问题大都在磁盘读写;
总结4:CPU负载多高算高?负载数不超高CPU颗粒数,就表示没有排队,CPU负载就不高;一般来说负载数不超高 CPU颗粒数的80%;
总结5:用户进程占用的CPU很低,系统内核占用的CPU很高可能是什么原因?
说明系统内核调用的比较多,调用内核频繁,写操作比较多,猜测可能是写数据库,写系统日志;
总结6:CPU什么时候读磁盘,什么时候写磁盘:CPU只在内存中干活,CPU需要的数据内存中没有就读磁盘,CPU的写操作,例如数据库的插入,写日志等的就是 CPU写磁盘;(写日志调用的是系统内核,CPU从用户进程切换到系统进程,消耗系统CPU)
分析思路:
top命令可以看到当前哪个进程占用的CPU最多,top -p 占用CPU最多的进程号 看到占用CPU最多的进程下的所有线程,进而找到占用CPU最高的线程;
启动Tomcat进程
top -p 进程号:切换到1721进程 显示如图3
在命令交换区输入“H” 显示如图4
图4是当前‘1721’进程下所有的线程