龙空技术网

Java 应用程序的 CPU 使用率飙升原因分析

wcmwcmchq 137

前言:

如今小伙伴们对“java进程cpu占用过高 死锁”大体比较关心,看官们都想要了解一些“java进程cpu占用过高 死锁”的相关知识。那么小编也在网络上汇集了一些对于“java进程cpu占用过高 死锁””的相关资讯,希望兄弟们能喜欢,小伙伴们一起来学习一下吧!

1、背景

在服务器上执行某个任务时,系统突然运行缓慢,top 发现cpu飙升,一度接近100%,最终导致服务假死。

2、CPU 使用率怎么计算?

CPU% = 1 - idleTime / sysTime * 100

idleTime:CPU处于空闲状态的时间sysTime:CPU处于用户态和内核台的时间总和

3、问题分析

#查看所有进程占系统cpu的排序,极大可能排第一的就是自己的java进程,pid就是进程号。1、top  #查看java进程下的所有线程占cpu情况。2、top -Hp 进程id #可查看进程堆栈信息3、jstack <options> 进程号  <options>-F	当正常输出的请求不被响应时,强制输出线程堆栈-m	如果调用到本地方法的话,可以显示C/C++的堆栈-l	除堆栈外,显示关于锁的附加信息,在发生死锁时可以用jstack -l pid来观察锁持有情况#查找某进程下-》线程id(jstack堆栈信息中的nid)=0xa的线程状态4、jstack 进程号 | grep 线程id最后可以把对应堆栈信息导入到log中,进行分析

jstack命令查看对应进程的堆栈信息

3、可能导致的原因

计算密集型的程序是比较耗 CPU 使用率的1、频繁GC,访问量高时,有可能造成频繁的YGC、甚至FGC。当调用量大时,内存分配过快,就会造成GC线程不停的执行,导致CPU飙高2、代码中有大量消耗CPU的操作,导致CPU过高,系统运行缓慢;     #例如某些复杂算法,甚至算法BUG,无限循环递归等等     3、由于锁使用不当,导致死锁4、序列化与反序列化,后文中举了一个真实的案例,程序执行xml解析的时,调用量增大的情况下,导致了CPU被打满5、加密、解密6、正则表达式校验,曾经线上发生一次血案,正则校验将CPU打满。大概原因是:Java 正则表达式使用的引擎实现是 NFA 自动机,这种引擎在进行字符匹配会发生回溯(backtracking)7、线程上下文切换、当启动了很多线程,而这些线程都处于不断的阻塞状态(锁等待、IO等待等)和执行状态的变化过程中。当锁竞争激烈时,很容易出现这种情况

4、常见的一些问题(来源于其他大佬的总结)

4-1.while的无限循环会导致CPU使用率飙升吗?

是。

首先,无限循环将调用CPU寄存器进行计数,此操作将占用CPU资源。那么,如果线程始终处于无限循环状态,CPU是否会切换线程?

除非操作系统时间片到期,否则无限循环不会放弃占用的CPU资源,并且无限循环将继续向系统请求时间片,直到系统没有空闲时间来执行任何其他操作。

4-2.频繁的Young GC会导致CPU占用率飙升吗?

是。

Young GC本身就是JVM用于垃圾收集的操作,它需要计算内存和调用寄存器。因此,频繁的Young GC必须占用CPU资源。

让我们来看一个现实世界的案例。for循环从数据库中查询数据集合,然后再次封装新的数据集合。如果内存不足以存储,JVM将回收不再使用的数据。因此,如果所需的存储空间很大,您可能会收到CPU使用率警报。

4-3.具有大量线程的应用程序的CPU使用率是否较高?

不是。

如果通过jstack检查系统线程状态时线程总数很大,但处于Runnable和Running状态的线程数不多,则CPU使用率不一定很高。

我遇到过这样一种情况:系统线程的数量是1000+,其中超过900个线程处于BLOCKED和WAITING状态。该线程占用很少的CPU。

但是大多数情况下,如果线程数很大,那么常见的原因是大量线程处于BLOCKED和WAITING状态。

4-4.对于CPU占用率高的应用程序,线程数是否较大?

不是。

高CPU使用率的关键因素是计算密集型操作。如果一个线程中有大量计算,则CPU使用率也可能很高。这也是数据脚本任务需要在大规模集群上运行的原因。

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

不会。

CPU使用率的飙升更多是由于上下文切换或过多的可运行状态线程。处于阻塞状态的线程不一定会导致CPU使用率上升。

4-6.如果分时操作系统中CPU的值us或sy值很高,这意味着什么?

可以使用命令查找CPU的值us和sy值top,如以下示例所示:

us:用户空间占用CPU的百分比。简单来说,高我们是由程序引起的。通过分析线程堆栈很容易找到有问题的线程。

sy:内核空间占用CPU的百分比。当sy为高时,如果它是由程序引起的,那么它基本上是由于线程上下文切换。

标签: #java进程cpu占用过高 死锁