2.技术-CPU飙高分析和排查(二)-CPU使用率分析
目录
一.背景
二.用户态和系统态(内核态)
三.CPU使用率
四.占用CPU分析
一.背景
在篇是在《技术-CPU飙高分析和排查(一)-CPU基础》之上。
本篇主要了解用户态和系统态。
二.用户态和系统态(内核态)
开机后操作系统会把物理内存逻辑的分为用户空间和系统空间。
用户空间:存放用户线程的数据,不允许访问外围设备例如硬盘,网卡。
系统空间:存放操作系统的数据。
处于用户态的程序只能访问用户空间的数据,目的是为了数据的隔离保证安全。
用户态切换到内核态的3种情况:
1>.系统调用(是由操作系统内核提供的一组函数,用户通过系统调用的命令即可在自己的程序中调用这些函数,这些函数与我们自己写的函数其实是一样的,只不过它是由操作系统提供)
这是用户态进程主动要求切换到内核态的一种方式,用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作,比如java中new一个线程就是系统调用。
2>.异常
当CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,会转到了内核态。
3>.外围设备的中断
当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号,这时CPU会暂停执行下一条即将要执行的指令转而去执行与中断信号对应的处理程序,如果先前执行的指令是用户态下的程序,那么这个转换的过程自然也就发生了由用户态到内核态的切换。比如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后续操作等,操作系统会重置CPU为用户态并返回系统调用的结果。
三.CPU使用率
%us : 就是用户态进程运行占用CPU的比例
%sy: 就是系统态进程运行占用CPU的比例
所以当我们CPU飙高,先分析是用户态高还是系统态高。
用户态高大部分是我们自己的代码引起的,系统态高则是说明程序中有调用内核态的方法占用高比如频繁的创建线程或者使用外围设备,后面详细介绍定位方法。
四.占用CPU分析
通过CPU的原理我们知道,我们的代码最终会被CPU一条一条的读取,翻译,处理。
所以每一行代码的执行都会占用CPU,这也解释随着请求量的增加CPU也会随之上升。因为每一次请求,对于CPU来说都会转换为一行行代码的处理。
下面我们先通过一些场景看下CPU的使用。(全部使用mac演示与Linux没有本质区别,只是展示不同)
下图是,未启动服务,top的截图。
1.用户态示例: