记一次 JVM CPU 使用率飙高问题的排查过程
点击上方“芋道源码”,选择“设为星标”
管她前浪,还是后浪?
能浪的浪,才是好浪!
每天 10:33 更新文章,每天掉亿点点头发...
源码精品专栏
问题现象
首先,我们一起看看通过 VisualVM 监控到的机器 CPU 使用率图:
如上图所示,在 下午3:45 分之前,CPU 的使用率明显飙高,最高飙到近 100%,为什么会出现这样的现象呢?
基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro 视频教程:https://doc.iocoder.cn/video/
排查过程
Step 1: 使用top命令,查询资源占用情况:
如上图所示,显示了服务器当前的资源占用情况,其中PID为5456的进程占用的资源最多。
在这里,我们也使用top -p PID
命令,查询指定PID的资源占用情况:
Step 2: 使用ps -mp PID -o THREAD,tid,time
命令,查询该进程的线程情况:
在这里,我们也使用ps -mp PID -o THREAD,tid,time | sort -rn
命令,将该进程下的线程按资源使用情况倒序展示:
Step 3: 使用printf "%x\n" PID
命令,将PID转为十六进制的TID:
在这里,我们之所以需要将PID转为十六进制是因为在堆栈信息中,PID是以十六进制形式存在的。
Step 4: 使用jstack PID | grep TID -A 100
命令,查询堆栈信息:
如上图所示,显示该进程下多个线程均处于TIMED_WAITING
状态。
虽然线程处于WAITING
或者TIMED_WAITING
状态都不会消耗 CPU,但是线程频繁的挂起和唤醒却会消耗 CPU,而且代价高昂。
而上面之所以会出现 CPU 使用率飙高的情况,则是因为有人在做压测。
特别地,在 mock 底层接口的时候,使用了类似TimeUnit.SECONDS.sleep(1)
这样的语句。
至于为何在 下午3:45 分之后,CPU 的使用率降下来了,则是因为停止了压测。
除此之外,我们还可以使用jinfo和jstat命令来查询 Java 进程的启动参数以及 GC 情况:
使用jinfo PID
命令,查询启动参数:
如上图所示,使用该命令我们主要是为了查询启动参数,如初始化堆大小、垃圾回收器等配置。
使用jstat -gcutil PID 1000
命令,查询 GC 情况:
如上图所示,显示了PID为20567的 Java 进程每秒的 GC 情况,其中1000表示 GC 状态的更新频率,单位为毫秒。
欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:
已在知识星球更新源码解析如下:
最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。
提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
微信扫码关注该文公众号作者