关于java:是什么让-Java-应用程序的-CPU-使用率飙升

13次阅读

共计 1939 个字符,预计需要花费 5 分钟才能阅读完成。

如果命运是一条孤单的河流,谁会是你的灵魂摆渡人?—— 克莱儿·麦克福尔《摆渡人》

一. 问题

  • 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 查看零碎线程状态时线程总数很大,但处于 RunnableRunning 状态的线程并不多,那么 CPU 使用率不肯定高。然而大多数状况下,如果线程数很大,那么常见的起因是大量线程处于 BLOCKEDWAITING 状态。

4. CPU 使用率高的应用程序的线程数肯定大吗?

答复:不肯定

剖析:CPU 使用率高的关键因素是计算密集型操作。如果一个线程有大量计算,CPU 使用率也可能很高,这也是一个数据脚本工作须要在大规模集群上运行的起因。

5. 处于 BLOCKED 状态的线程是否会导致 CPU 使用率飙升?

答复:不肯定

剖析:CPU 使用率的飙升更多是因为上下文切换或过多的可运行状态线程。处于阻塞状态的线程不肯定会导致 CPU 使用率回升。

6 . CPU 的 ussy值在分时操作系统中高是什么意思?

咱们能够应用 top 命令查看 CPU 的 ussy 的值,如下图所示:

  • 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

正文完
 0