如果命运是一条寂寞的河流,谁会是你灵魂的渡口?-ClaireMcFaul《摆渡人》1.Questionwhile的死循环会导致CPU占用率飙升吗?频繁的YoungGC是否会导致CPU使用率激增?线程数多的应用是否CPU占用率高?CPU密集型应用程序的线程数是否很高?处于BLOCKED状态的线程是否会导致CPU使用率飙升?分时操作系统中CPU是消耗us(用户态)还是sy(内核态)?二、思考1、我们如何计算CPU占用率?CPU%=(1-idleTime/sysTime)*100idleTime:CPU的空闲时间sysTime:CPU处于用户态和内核态的时间总和2.常见的CPU密集型操作有哪些?人们常说计算密集型程序是CPU密集型的,那么Java应用程序中哪些操作是计算密集型的呢?常见的CPU密集型操作如下:频繁GC;如果访问量很大,可能会导致频繁GC甚至FullGC。当调用次数多时,内存分配会很快,导致GC线程不断执行,导致CPU飙升。序列化和反序列化加密和解码的正则表达式。原因可能是Java正则表达式使用的引擎实现是一个NFA自动机,当字符匹配时回溯。线程上下文切换。有很多已启动的线程,其状态在Blocked(锁等待、IO等待等)和Running之间不断变化,这在锁竞争较高时很容易发生。一些线程正在执行非阻塞操作,例如while(true)语句。如果程序中的计算时间较长,可以休眠线程。3、CPU和进程、线程有关系吗?现在,分时操作系统采用轮询的方式分配时间片进行进程调度。如果进程处于等待或阻塞状态,则它不会使用CPU资源。线程被称为轻进程,共享进程资源,所以线程调度在CPU中也是分时的。但是在Java中,我们是使用JVM来进行线程调度的,所以一般来说,线程调度有两种模式:分时调度和抢占式调度。线程和进程在阻塞或等待时都不使用CPU资源。三、答1、while的死循环会导致CPU占用率飙升吗?答:可以分析:首先死循环会调用CPU寄存器进行计数,这个操作会占用CPU资源。那么,如果线程一直在死循环,CPU会不会切换线程呢?除非操作系统时间片到期,死循环不会放弃占用的CPU资源,死循环会不断向系统申请时间片,直到系统没有空闲时间做其他事情。2、频繁的YoungGC会不会导致CPU占用率飙升?答:是分析:YoungGC本身就是JVM进行垃圾回收的操作,需要计算内存和调用寄存器,所以频繁的YoungGC肯定会占用CPU资源。我们来看一个真实的案例:for循环从数据库中查询数据集合,然后重新包装新的数据集合。如果没有足够的内存用于存储,JVM将回收未使用的数据。因此,如果所需的存储空间很大,您可能会收到CPU使用率警报。3.线程多的应用一定CPU占用率高吗?答:不一定分析:如果我们通过jstack查看系统线程状态时线程总数比较大,但是处于Runnable和Running状态的线程并不多,那么CPU占用率可能并不高。但在大多数情况下,如果线程数较多,常见的原因是大量线程处于BLOCKED和WAITING状态。4.CPU使用率高的应用程序线程数一定要高吗?答:不一定分析:CPU使用率高的主要原因是计算密集型操作。如果线程有很多计算,CPU使用率也会很高,这就是为什么数据脚本任务需要在大型集群上运行的原因。5.处于BLOCKED状态的线程会导致CPU使用率飙升吗?答:不一定分析:CPU使用率飙升更多是因为上下文切换或者runnable状态线程过多。阻塞的线程不一定会导致CPU使用率增加。6、分时操作系统中CPU的us和sy值偏高是什么意思?我们可以使用top命令查看CPU的us和sy的值,如下图所示:us:用户空间占用CPU的百分比。简单的说,如果us的值比较高,就是我们的程序造成的,通过分析线程栈很容易定位出问题的线程。sy:内核空间占用CPU的百分比。当sy为高时,如果是程序引起的,基本是线程上下文切换引起的。4.体验如何定位CPU占用率高的原因?下面简述分析过程。如果发现某个应用服务器CPU占用率高,首先要查看线程数、JVM、系统负载等参数,然后通过这些参数来证明问题的原因。其次,使用jstack打印堆栈信息,使用工具分析线程使用情况(推荐使用在线线程分析工具fastThread)。在线线程分析工具fastThread地址:https://fastthread.io/下一篇介绍如何使用在线线程分析工具fastThread分析线程堆栈信息。参考文档:https://www.tutorialdocs.com/article/java-cpu-soar.html
