深入拆解 Tomcat & Jetty
李号双
eBay 技术主管
38890 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 45 讲
开篇词 (1讲)
深入拆解 Tomcat & Jetty
15
15
1.0x
00:00/00:00
登录|注册

39 | Tomcat进程占用CPU过高怎么办?

线程上下文切换活动
线程状态
使用jstack命令生成线程快照
使用top -H命令查看线程CPU使用情况
使用top命令查看CPU使用率
启动程序
编写模拟程序
进一步分析上下文切换开销
定位高CPU使用率的线程和代码
确认线程上下文切换开销
查看具体线程
定位问题进程
线程数失控可能原因
确认线程上下文切换开销
查看线程状态
定位具体线程
定位问题进程
CPU问题
网络相关问题
内存问题
精华
课后思考
解决思路
Tomcat
性能优化

该思维导图由 AI 生成,仅供参考

在性能优化这个主题里,前面我们聊过了 Tomcat 的内存问题和网络相关的问题,接下来我们看一下 CPU 的问题。CPU 资源经常会成为系统性能的一个瓶颈,这其中的原因是多方面的,可能是内存泄露导致频繁 GC,进而引起 CPU 使用率过高;又可能是代码中的 Bug 创建了大量的线程,导致 CPU 上下文切换开销。
今天我们就来聊聊 Tomcat 进程的 CPU 使用率过高怎么办,以及怎样一步一步找到问题的根因。

“Java 进程 CPU 使用率高”的解决思路是什么?

通常我们所说的 CPU 使用率过高,这里面其实隐含着一个用来比较高与低的基准值,比如 JVM 在峰值负载下的平均 CPU 利用率为 40%,如果 CPU 使用率飙到 80% 就可以被认为是不正常的。
典型的 JVM 进程包含多个 Java 线程,其中一些在等待工作,另一些则正在执行任务。在单个 Java 程序的情况下,线程数可以非常低,而对于处理大量并发事务的互联网后台来说,线程数可能会比较高。
对于 CPU 的问题,最重要的是要找到是哪些线程在消耗 CPU,通过线程栈定位到问题代码;如果没有找到个别线程的 CPU 使用率特别高,我们要怀疑到是不是线程上下文切换导致了 CPU 使用率过高。下面我们通过一个实例来学习 CPU 问题定位的过程。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Tomcat进程占用CPU过高是一个常见的系统性能问题,可能由内存泄露、线程创建过多等多种原因引起。本文介绍了解决Tomcat进程CPU使用率过高的思路和方法。首先,作者提到了定位高CPU使用率的线程和代码的步骤,通过编写模拟程序、使用top命令和jstack命令来找出消耗CPU的线程和定位问题代码。其次,文章进一步分析了上下文切换开销,指出了线程池中的线程处于等待状态,导致CPU消耗增加。最后,文章总结了解决高CPU使用率问题的关键步骤,并提出了课后思考的问题,引导读者深入思考和讨论。通过本文,读者可以了解到解决CPU过高问题的具体步骤和方法,对于系统性能优化具有一定的指导意义。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深入拆解 Tomcat & Jetty 》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(18)

  • 最新
  • 精选
  • a、
    1.使用了Java的newCachedThreadPool,因为最大线程数是int最大值 2.自定义线程池最大线程数设置不合理 3.线程池的拒绝策略,选择了如果队列满了并且线程达到最大线程数后,提交的任务交给提交任务线程处理

    作者回复: 赞

    2019-08-10
    3
    19
  • 802.11
    老师这些都是一些实时的操作,但是大部分情况CPU高的时候并没有及时的在服务器上观察,一旦错过了这个发生的时间点,事后该怎样去判断和定位呢

    作者回复: 这确实是个问题。监控系统一般会将各种指标包括cpu,内存等存下来,但是打印出线程栈,heapdump这些需要手动操作

    2019-08-10
    2
    9
  • 802.11
    TIMED_WAITING 是什么意思呢?有什么寓意呢

    作者回复: 根据TCP协议,主动发起关闭的一方,会进入TIME_WAIT状态

    2019-08-10
    3
    4
  • 陆离
    容器在启动起来之后就被kill掉的原因有哪些?和CPU过高有关系吗

    作者回复: 如何确定是“被kill”呢,或者是异常退出?如果是被kill,看是被谁kill了

    2019-08-10
  • 新世界
    线程池和等待队列设置不合理以及拒绝策略设置不合理会导致线程数失控,比如线程池设置小,等到队列也不大,拒绝策略选择用主线程继续执行,瞬间大量请求,会导致等到队列占满,进而用主线程执行任务,导致tomcat线程被打满,线程数失控
    2019-08-10
    5
  • Edward Lee
    课后思考 之前做了一个与第三方系统的集成,在未设置读超时时间的前提下发生读超时(卡着接近2分钟),导致Tomcat线程耗尽,并同时出现假死情况
    2020-12-06
    3
  • 花花大脸猫
    大量处理时间很长的请求,外加未规划的tomcat连接配置,会导致线程数随着请求量的增大无限递增。
    2022-06-22
    1
  • JamesZhou
    排查CPU过高,发现一个小工具可以试试:https://github.com/oldratlee/useful-scripts/blob/dev-2.x/docs/java.md#-show-busy-java-threads
    2020-05-31
    1
  • 花花世界小人物
    Blocking 指的是一个线程因为等待临界区的锁(Lock 或者 synchronized 关键字)而被阻塞的状态,请你注意的是处于这个状态的线程还没有拿到锁 老师 Blocking状态只有synchronized阻塞的时候才会有这个状态。我试了一下ReentrantLock锁是WAITING "222" #14 prio=5 os_prio=31 tid=0x00007f852d20a800 nid=0x9503 waiting on condition [0x0000000306dc1000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x000000076cb6eb48> (a java.util.concurrent.locks.ReentrantLock$NonfairSync) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199) at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209) at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285) at cn.labnetwork.service.order.requisition.RequisitionController$1.run(RequisitionController.java:123) at java.lang.Thread.run(Thread.java:750)
    2023-03-03归属地:上海
  • DY
    老师真牛
    2021-05-17
收起评论
显示
设置
留言
18
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部