Tomcat进程占用CPU过高怎么办?(上)

简介: Tomcat进程占用CPU过高怎么办?

CPU经常会成为系统性能的瓶颈,可能:

  • 内存泄露导致频繁GC,进而引起CPU使用率过高
  • 代码Bug创建了大量的线程,导致CPU频繁上下文切换


通常所说的CPU使用率过高,隐含着一个用来比较高与低的基准值,比如

  • JVM在峰值负载下的平均CPU利用率40%
  • CPU使用率飙到80%就可认为不正常


JVM进程包含多个Java线程:

  • 一些在等待工作
  • 另一些则正在执行任务


最重要的是找到哪些线程在消耗CPU,通过线程栈定位到问题代码

如果没有找到个别线程的CPU使用率特别高,考虑是否线程上下文切换导致了CPU使用率过高。

案例

程序模拟CPU使用率过高 - 在线程池中创建4096个线程


在Linux环境下启动程序:

java -Xss256k -jar demo-0.0.1-SNAPSHOT.jar

线程栈大小指定为256KB。对于测试程序来说,操作系统默认值8192KB过大,因为需要创建4096个线程。


使用top命令,我们看到Java进程的CPU使用率达到了961.6%,注意到进程ID是55790。

image.png

用更精细化的top命令查看这个Java进程中各线程使用CPU的情况:

#top -H -p 55790

1.png

可见,有个叫“scheduling-1”的线程占用了较多的CPU,达到了42.5%。因此下一步我们要找出这个线程在做什么事情。

  1. 为了找出线程在做什么,用jstack生成线程快照。
    jstack输出较大,一般将其写入文件:
jstack 55790 > 55790.log

打开55790.log,定位到第4步中找到的名为 scheduling-1 的线程,其线程栈:

image.png

看到AbstractExecutorService#submit这个函数调用,说明它是Spring Boot启动的周期性任务线程,向线程池中提交任务,该线程消耗了大量CPU。

上下文切换开销?

经历上述过程,往往已经可以定位到大量消耗CPU的线程及bug代码,比如死循环。但对于该案例:Java进程占用的CPU是961.6%, 而“scheduling-1”线程只占用了42.5%的CPU,那其它CPU被谁占用了?


第4步用top -H -p pid命令看到的线程列表中还有许多名为“pool-1-thread-x”的线程,它们单个的CPU使用率不高,但是似乎数量比较多。你可能已经猜到,这些就是线程池中干活的线程。那剩下的CPU是不是被这些线程消耗了呢?


还需要看jstack的输出结果,主要是看这些线程池中的线程是不是真的在干活,还是在“休息”呢?


image.png

image.png

发现这些“pool-1-thread-x”线程基本都处WAITING状态。

image.png

  • Blocking指的是一个线程因为等待临界区的锁(Lock或者synchronized关键字)而被阻塞的状态,请你注意的是处于这个状态的线程还没有拿到锁
  • Waiting指的是一个线程拿到了锁,但需等待其他线程执行某些操作。比如调用了Object.wait、Thread.join或LockSupport.park方法时,进入Waiting状态。前提是这个线程已经拿到锁了,并且在进入Waiting状态前,os层面会自动释放锁,当等待条件满足,外部调用了Object.notify或者LockSupport.unpark方法,线程会重新竞争锁,成功获得锁后才能进入到Runnable状态继续执行。


目录
相关文章
|
3月前
|
Linux
|
6月前
|
Java
一文解析!Java进程CPU100%打满
背景 最近发现测试服务器经常触发CPU90%报警,这次有空了,决定上服务器分析一下,居然发现是最近新上线的日志收集服务消耗大量CPU: top 资源消耗分析, shift + p 根据CPU消耗排序,shift + m 根据内存消耗排序 一个进程CPU消耗超过90%CPU,第一眼感觉不正常,因此进行了一番分析。 CPU分析 1.使用 top -p 命令(为Java进程的id号)查看Java进程的cpu占用: top -p 29595 查看指定进程资源使用情况 2.使用 top -Hp 命令(为Java进程的id号)查看该Java进程内所有线程的资源占用情况 top -Hp 2
|
3月前
|
Linux 调度
linux中进程与cpu核的绑定
linux中进程与cpu核的绑定
67 0
|
5月前
|
负载均衡 算法 Linux
深入理解Linux内核进程CPU负载均衡机制(上)
深入理解Linux内核进程CPU负载均衡机制
|
2月前
|
网络协议 Linux
【系统DFX】如何诊断占用过多 CPU、内存、IO 等的神秘进程?
【系统DFX】如何诊断占用过多 CPU、内存、IO 等的神秘进程?
111 0
|
3月前
|
存储 JSON 运维
【运维】Powershell 服务器系统管理信息总结(进程、线程、磁盘、内存、网络、CPU、持续运行时间、系统账户、日志事件)
【运维】Powershell 服务器系统管理信息总结(进程、线程、磁盘、内存、网络、CPU、持续运行时间、系统账户、日志事件)
49 0
|
4月前
|
安全 Unix Linux
Linux【问题记录 02】腾讯云 cron、sshd 进程CPU占用超95%(亡命徒 Outlaw 僵尸网络攻击)问题排查及处理步骤
Linux【问题记录 02】腾讯云 cron、sshd 进程CPU占用超95%(亡命徒 Outlaw 僵尸网络攻击)问题排查及处理步骤
61 0
|
5月前
|
NoSQL Shell Linux
跨cpu架构部署容器技术点:怎么将容器启动时的1号进程挂载到systemctl
--privileged=true:是Docker中的一个参数,用于授予容器的特权权限。当一个容器被设置为特权容器时,它将拥有与主机操作系统相同的权限,可以执行一些高级操作,如访问主机设备、加载内核模块等。
44 0
|
5月前
|
负载均衡 算法 Linux
深入理解Linux内核进程CPU负载均衡机制(下)
深入理解Linux内核进程CPU负载均衡机制
|
8月前
|
消息中间件 存储 缓存
【多线程系列-01】深入理解进程、线程和CPU之间的关系
【多线程系列-01】深入理解进程、线程和CPU之间的关系
32174 14

相关实验场景

更多