龙空技术网

这可能是全网分析java应用cpu使用率飙升最全的文章

Java技术架构 4370

前言:

眼前同学们对“java进程cpu占用过高 死锁”大体比较着重,你们都想要分析一些“java进程cpu占用过高 死锁”的相关资讯。那么小编在网上网罗了一些对于“java进程cpu占用过高 死锁””的相关文章,希望你们能喜欢,大家一起来了解一下吧!

专注于Java领域优质技术号,欢迎关注

作者:王洪涛

作者简介京东商城,商家研发部架构师。丰富的构建高性能高可用大规模分布式系统的研发、架构经验。2015年加入京东,目前负责服务市场的系统研发工作。

疑惑一个 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 使用的?

列举日常程序中常见的耗CPU的操作:

频繁GC,访问量高时,有可能造成频繁的GC、甚至FGC。当调用量大时,内存分配过快,就会造成GC线程不停的执行,导致CPU飙高序列化与反序列化,后文中举了一个真实的案例,程序执行xml解析的时,调用量增大的情况下,导致了CPU被打满加密、解密正则表达式校验,曾经线上发生一次血案,正则校验将CPU打满。大概原因是:Java 正则表达式使用的引擎实现是 NFA 自动机,这种引擎在进行字符匹配会发生回溯(backtracking)线程上下文切换、当启动了很多线程,而这些线程都处于不断的阻塞状态(锁等待、IO等待等)和执行状态的变化过程中。当锁竞争激烈时,很容易出现这种情况某些线程在做无阻塞的运算,简单的例子while(true)中不停的做运算,没有任何阻塞。写程序时,如果需要做很久的计算,可以适当将程序sleep下

3、CPU 与进程、线程有关系么?

现在分时操作系统是通过循轮方式分配时间片进行进程调度的,如果进程在等待或阻塞,不会造成 CPU 资源使用。线程称为轻进程,共享进程资源,关于线程的调度,CPU 对于线程也是分时调度。而在 Java 中,线程的调用由 JVM 负责,线程的调度一般有两种模式,分时调度和抢占式调度。

解惑

1、一个 while 死循环,会不会引起 CPU 使用率飚升?

会的。

先不说别的,死循环会调用 CPU 寄存器进行计数,这个操作就会占用 CPU。其次,如果线程一直处于死循环状态,CPU 调用会进行线程切换么?

死循环不会让出 CPU,除非操作系统时间片到期,但死循环会不断向系统申请时间片,直到系统没有空闲时间做别的事情。

这个问题在 stackoverflow 也有人提问:why does an infinite loop of the unintended kind increase the CPU use?

地址:

2、频繁 Young GC 会不会引起 CPU 使用率飚升?

会的。

Young GC 本身是 JVM 进行垃圾回收的操作,会计算内存和调用寄存器,频繁 Young GC 一定是会占用 CPU。

之前有个一个案例,for 循环从数据库查询数据集合,二次封装新的数据集合,这时如果量比较大时,内存没有足够的空间存储,那么 JVM 就会 GC 回收那些不再使用的数据,因此量大的时候,就会收到 CPU 使用率报警。

3、线程数很高的应用,CPU 使用率一定高么?

不会。

通过 jstack 查看系统线程状态,查看整个线程数很多,但 Runable 和 Running 状态的线程不多,这时 CPU 使用率不一定会高。

之前有过一个案例,查看系统线程数 1000+,jstack 分析 900多个线程是 BLOCKED 和 WAITING 状态的,这种线程是不会占用 CPU 的。

如果线程数很高,其实大多数原因是死锁,大量线程处于 BLOCKED 和 WAITING 状态。

4、CPU 使用率高的应用,线程数一定高么?

不会。

同上,CPU 使用率高的关键因素还是计算密集型操作,一个线程如果有大量计算,也会造成 CPU 使用率高,也是现在为什么一个大数据脚本任务,要大规模集群共同运算才能运行的原因。

5、BLOCKED 状态的线程会不会引起 CPU 使用率飚升?

不一定。

CPU使用率的飙升,更多是因为上下文的切换或者runnable状态线程过多导致。Blocked状态,未必会引起CPU上升。

6、分时操作系统 CPU us高或者sy高是什么意思?

通过top命令,可以观察到CPU的us,sy值,示例如下:

us 用户空间占用CPU百分比,简单来说,us高是因为程序导致的,通过分析线程堆栈,可以很容易的定位到问题线程。sy 内核空间占用CPU百分比,sy高的时候,如果是程序问题导致,基本是因为线程上下文切换造成的。经验

平时怎么定位 CPU 使用率高的原因?网上有个教程和方法,下面简述一下分析过程。

首先发现某台应用 CPU 使用率高,一要看先线程数、JVM、系统 load 等参数,共同作证。二要打印 jstack,通过工具分析线程情况,推荐 fastThread 这个在线的 Thread 分析工具。

以下是线上发生的真实案例,简要介绍下:

某日晚,突然收到短信报警,CPU利用率100%。立刻dump该机器jstack,通过 查看日志如下:

进一步查看具体日志:

通过这段日志,已经定位到了具体CPU被打满的方法,接收MQ之后,MQ消息体为xml,反序列化的时候,造成了CPU飙高。

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