如果命运是一条孤单的河流,谁会是你的灵魂摆渡人?—— 克莱儿·麦克福尔《摆渡人》
一. 问题
- while 的有限循环是否会导致 CPU 使用率飙升?
- 频繁的 Young GC 是否会导致 CPU 使用率飙升?
- 有大量线程的应用程序的 CPU 使用率高吗?
- CPU 使用率高的应用程序的线程数是否很大?
- 处于 BLOCKED 状态的线程是否会导致 CPU 使用率飙升?
- 分时操作系统中的 CPU 是耗费
us(用户态)
还是sy(内核态)
?
二. 思考
1. 咱们如何计算 CPU 使用率?
CPU% = (1 - idleTime / sysTime) * 100
idleTime
:CPU 的闲暇工夫sysTime
:CPU 处于用户态和内核态的工夫总和
2. 常见的 CPU 密集型操作有哪些?
人们常说,计算密集型程序就是 CPU 密集型的,那么,Java 应用程序中有哪些操作是计算密集型的呢?
上面列出常见 CPU 密集型操作:
- 频繁的 GC;如果访问量很大,可能会导致频繁的 GC 甚至 Full GC。当调用量大时,内存调配会十分快,以至于 GC 线程会一直执行,导致 CPU 飙升。
- 序列化和反序列化
- 加密和解码
- 正则表达式。起因可能是 Java 正则表达式应用的引擎实现是 NFA 自动机,它会在字符匹配时进行回溯。
- 线程上下文切换。有很多启动的线程,这些线程的状态在 Blocked(锁期待、IO 期待等)和 Running 之间一直变动,当锁争用强烈时,这种状况很容易产生。
- 一些线程正在执行非阻塞操作,例如
while (true)
语句。如果程序中计算工夫较长,能够休眠线程。
3. CPU 与 过程和线程无关吗?
当初,分时操作系统采纳轮询的形式为过程调度调配工夫片。如果过程正在期待或阻塞,则它不会应用 CPU 资源。线程称为轻过程,共享过程资源,因而线程调度在 CPU 中也是分时的。然而在 Java 中,咱们应用 JVM 进行线程调度,所以一般来说,线程的调度有两种模式:分时调度和抢占式调度。线程和过程在阻塞或者期待时,都不会应用 CPU 资源。
三. 答案
1. while 的有限循环是否导致 CPU 使用率飙升?
答复:是的
剖析:首先,有限循环会调用 CPU 寄存器进行计数,这个操作会占用 CPU 资源。那么,如果线程始终处于死循环状态,CPU 会不会切换线程呢?除非操作系统工夫片到期,否则有限循环不会放弃占用的 CPU 资源,并且有限循环会持续向零碎申请工夫片,直到零碎没有闲暇工夫做其余事件。
2. 频繁的 Young GC 会导致 CPU 使用率飙升吗?
答复:是的
剖析:Young GC 自身就是 JVM 进行垃圾回收的操作,须要计算内存和调用寄存器,因而频繁的 Young GC 必定会占用 CPU 资源。
让咱们来看一个实在的案例:for 循环从数据库中查问数据汇合,而后再次封装新的数据汇合。如果内存不够存储,JVM 会回收不再应用的数据。因而,如果须要的存储空间很大,可能会收到 CPU 使用率警报。
3. 线程多的利用 CPU 使用率肯定高吗?
答复:不肯定
剖析:如果咱们通过 jstack
查看零碎线程状态时线程总数很大,但处于 Runnable
和 Running
状态的线程并不多,那么 CPU 使用率不肯定高。然而大多数状况下,如果线程数很大,那么常见的起因是大量线程处于 BLOCKED
和 WAITING
状态。
4. CPU 使用率高的应用程序的线程数肯定大吗?
答复:不肯定
剖析:CPU 使用率高的关键因素是计算密集型操作。如果一个线程有大量计算,CPU 使用率也可能很高,这也是一个数据脚本工作须要在大规模集群上运行的起因。
5. 处于 BLOCKED 状态的线程是否会导致 CPU 使用率飙升?
答复:不肯定
剖析:CPU 使用率的飙升更多是因为上下文切换或过多的可运行状态线程。处于阻塞状态的线程不肯定会导致 CPU 使用率回升。
6 . CPU 的 us
和sy
值在分时操作系统中高是什么意思?
咱们能够应用 top
命令查看 CPU 的 us
和 sy
的值,如下图所示:
- us:用户空间占用 CPU 的百分比。简略来说,如果
us
的值比拟高,则是咱们程序引起的,并且剖析线程堆栈很容易定位有问题的线程。 - sy:内核空间占用 CPU 的百分比。
sy
高的时候,如果是程序引起的,那么基本上是线程上下文切换引起的。
四. 教训
如何定位 CPU 使用率高的起因?上面简要介绍剖析过程。
如果发现某个应用服务器的 CPU 使用率高,首先查看 线程数、JVM、零碎负载 等参数,而后用这些参数来证实问题的起因。其次,用 jstack 打印堆栈信息,应用工具剖析线程应用状况(举荐应用在线线程剖析工具 fastThread)。
在线线程剖析工具 fastThread 地址:https://fastthread.io/
下一篇文章介绍如何应用在线线程剖析工具 fastThread 剖析线程堆栈信息。
参考文档:
https://www.tutorialdocs.com/article/java-cpu-soar.html