Java进程CPU高负载排查

news2024/12/24 21:25:13

Java进程CPU高负载排查步骤_java进程cpu使用率高排查_YouluBank的博客-CSDN博客
【问题定位】使用arthas定位CPU高的问题_arthas cpu高_秋装什么的博客-CSDN博客

CPU飙升可能原因

  1. CPU 上下文切换过多。
    1. 对于 CPU 来说,同一时刻下每个 CPU 核心只能运行-个线程,如果有多个线程要执行,CPU 只能通过上下文切换的方式来执行不同的线程。
    2. 上下文切换需要做两个事情:保存运行线程的执行状态;让处于等待中的线程执行
    3. 这两个过程需要 CPU 执行内核相关指令实现状态保存,如果较多的上下文切换会占据大量 CPU 资源,从而使得 cpu 无法去执行用户进程中的指令,导致响应速度下降。
  2. 在 Java 中,文件1O、网络 1O、锁等待、线程阻塞等操作都会造成线程阻塞从而触发上下文切换
  3. CPU 资源过度消耗,也就是在程序中创建了大量的线程,或者有线程一直占用CPU 资源无法被释放,比如死循环!
  4. CPU 利用率过高之后,导致应用中的线程无法获得 CPU 的调度,从而影响程序的执行效率!

使用命令查找

采用top命令定位进程

登录服务器,执行top命令,查看CPU占用情况,找到进程的pid
image.png

很容易发现,PID为29706的java进程的CPU飙升到700%多,且一直降不下来,很显然出现了问题。

使用top -Hp命令定位线程

使用 top -Hp 命令(为Java进程的id号)查看该Java进程内所有线程的资源占用情况

top -Hp 29706

很容易发现,多个线程的CPU占用达到了90%多。我们挑选线程号为30309的线程继续分析。
image.png

使用jstack命令定位代码

线程号转换为16进制

printf “%x\n” 命令(tid指线程的id号)将以上10进制的线程号转换为16进制:

printf "%x\n"  30309

转换后的结果分别为7665,由于导出的线程快照中线程的nid是16进制的,而16进制以0x开头,所以对应的16进制的线程号nid为0x7665
image.png

采用jstack命令导出线程快照

通过使用dk自带命令jstack获取该java进程的线程快照并输入到文件中: jstack -l > ./jstack_result.txt 命令(为Java进程的id号)来获取线程快照结果并输入到指定文件。

jstack -l 29706 > ./jstack_result.txt

根据线程号定位具体代码

在jstack_result.txt 文件中根据线程好nid搜索对应的线程描述

cat jstack_result.txt |grep -A 100  7665

image.png
根据搜索结果,判断应该是ImageConverter.run()方法中的代码出现问题
也可以直接采用jstack |grep -A 200 来定位具体代码

jstack 29706 |grep -A 200 7665
"System Clock" #28 daemon prio=5 os_prio=0 tid=0x00007efc19e8e800 nid=0xae24 waiting on condition [0x00007efbe0d91000]

java.lang.Thread.State: TIMED_WAITING (sleeping)

at java.lang.Thread.sleep(Native Method)

at java.lang.Thread.sleep(Thread.java:340)

at java.util.concurrentC.TimeUnit.sleep(TimeUnit.java:386)

at com.*.order.Controller.OrderController.detail(OrderController.java:37) //业务代码阻塞点

使用工具查找

使用arthas

下载arthas

curl -O https://arthas.aliyun.com/arthas-boot.jar

1
启动arthas

java -jar arthas-boot.jar

选择3,进行监听我们的应用程序。

模拟CPU高的场景

    @GetMapping("/cpu")
    public void cpu() {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 5, 1000, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100));
        threadPoolExecutor.execute(new Runnable() {
            public void run() {
                while (true) {
                    log.info(System.currentTimeMillis() + "");
                }
            }
        });
    }

dashboard
image.png

thread -n {number}

按照CPU使用率排序,并展示前n个线程
image.png

thread [pid]

展示指定线程的线程栈
image.png
模拟查看方法调用耗时

@RestController
@Slf4j
public class TestController {


    @RequestMapping("/trace")
    public String trace(int number) throws InterruptedException {
        number++;
        fun1(number);
        return "Hello World!";
    }

    private void fun1(int number) throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(10);
        number++;
        fun2(number);
    }

    private void fun2(int number) throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(300);
        number++;
        fun3(number);
    }

    private void fun3(int number) throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(20);
    }
}

trace

trace com.charles.web.TestController trace,监听TestController的trace方法。
image.png
访问wget http://localhost:7077/trace?number=1,可以看出trace和fun1方法的耗时。
trace命令只会匹配当前的方法,以及下一级方法。
trace -E com.charles.web.TestController trace|fun1|fun2|fun3
image.png
可以看出fun2方法耗时比较长。

watch

watch com.charles.web.TestController fun2 “{params,returnObj}” -x 2 -b,watch方法可以观察到入参,此时入参是3。
image.png

其它情况

从gc角度出发,是否存在大量gc,首先确定当前内存消耗情况,使用top命令或者查看设备监控管理系统,确定内存利用率达97%:

总结

CPU飙升问题定位的一般步骤是:
1.首先通过top指令查看当前占用CPU较高的进程PID;
2.查看当前进程消耗资源的线程PID: top -Hp PID
3.通过print命令将线程PID转为16进制,根据该16进制值去打印的堆栈日志内查询,查看该线程所驻留的方法位置。
4.通过jstack命令,查看栈信息,定位到线程对应的具体代码。
5.分析代码解决问题。

image.png
image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1510867.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JAVA实战开源项目:生活废品回收系统(Vue+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容三、界面展示3.1 登录注册3.2 资源类型&资源品类模块3.3 回收机构模块3.4 资源求购/出售/交易单模块3.5 客服咨询模块 四、免责说明 一、摘要 1.1 项目介绍 生活废品回收系统是可持续发展的解决方案&#xff0c;旨在鼓…

最新APP开发趋势,探索2024年的创新与挑战

2024年&#xff0c;移动应用市场仍然是创新与变革的焦点。随着技术的不断发展和用户需求的不断变化&#xff0c;APP开发行业也在不断演进。本文将深入探讨2024年最新的APP开发趋势&#xff0c;以及所带来的创新与挑战&#xff0c;并介绍虎克技术公司提出的解决方案。 1. 强调用…

AIGC笔记--Maya提取和修改FBX动作文件

目录 1--Maya数据解析 2--FBX SDK导出6D数据 3--6D数据映射和Maya可视化 完整项目代码&#xff1a;Data-Processing/FBX_SDK_Maya 1--Maya数据解析 在软件Maya中直接拖入FBX文件&#xff0c;可以播放和查看人体各个骨骼关节点的数据&#xff1a; 对于上图来说&#xff0c;…

【傻瓜文档】鼎利测试软件Pilot Pioneer-① Pioneer界面介绍

Pioneer界面分布 工具栏 自定义快速访问工具栏 根据需求&#xff0c;自行制定工具栏选项 菜单栏 文件 语言 配置 工具 工具栏的补充内容&#xff0c;常用的有&#xff1a;合并/分割数据、GPS轨迹补偿等等。 帮助

亿发定制:中小型生产制造工厂为什么需要建设企业信息化管理?

随着互联网行业的迅猛发展&#xff0c;越来越多的加工制造业企业将互联网作为核心枢纽&#xff0c;这一关键核心枢纽即为企业信息化管理。 在企业信息化管理中&#xff0c;主要包括三个关键方面&#xff1a;企业变革过程管理、企业运作管理&#xff0c;以及信息技术、信息资源…

【YUNBEE云贝技术分享】如何定位postgreSQL数据库中未被使用过的索引

注: 本文为云贝教育 刘峰 原创&#xff0c;请尊重知识产权&#xff0c;转发请注明出处&#xff0c;不接受任何抄袭、演绎和未经注明出处的转载。 前言 在生产环境上&#xff0c;由于不规范的优化措施&#xff0c;数据库中可能存在大量的索引&#xff0c;并且相当一部分的索引…

jeecgboot 开放页面权限,免登录访问

前端需要配置路由和添加白名单 1、配置路由 2、 在permission.js里&#xff0c;把刚才的路由添加到白名单 3、 后端需要把该页面涉及到的接口排除权限拦截 比如我这个页面涉及到两个接口&#xff1a; 那么就在后端的excludeUrls把这两个接口加进去。 前端后端都设置好了&…

idea实现ssh远程连接服务器

1. 首先&#xff0c;打开idea&#xff0c;点击左上角File->settings 2. 点击tools->SSH Configurations->填写必要的信息&#xff0c;Host就是访问服务器的ip地址&#xff0c;Username就是服务器的用户账户&#xff0c;比如root&#xff0c;Password账户对应的密码&am…

智慧城市与绿色出行:共同迈向低碳未来

随着城市化进程的加速&#xff0c;交通拥堵、空气污染、能源消耗等问题日益凸显&#xff0c;智慧城市与绿色出行成为了解决这些问题的关键途径。智慧城市利用信息技术手段&#xff0c;实现城市各领域的智能化管理和服务&#xff0c;而绿色出行则强调低碳、环保的出行方式&#…

【Golang】golang使用三方SDK操作容器指南

【Golang】golang使用三方SDK操作容器指南 大家好 我是寸铁&#x1f44a; 总结了一篇 golang使用三方SDK操作容器✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 这应该是目前全网最全golang使用三方SDK操作容器的指南了✌️ CreateConfig 主要是创建容器的配置信息&#xff0c;常…

【Java从发入门到精通】Java StringBuffer 和 StringBuilder 类

Java StringBuffer 和 StringBuilder 类 当对字符串进行修改的时候&#xff0c;需要使用 StringBuffer 和 StringBuilder 类。 和 String 类不同的是&#xff0c;StringBuffer 和 StringBuilder 类的对象能够被多次的修改&#xff0c;并且不产生新的未使用对象。 在使用 Stri…

#QT(QSpinBox,QDoubleSpinBox)

1.IDE&#xff1a;QTCreator 2.实验:实现一个计价工具&#xff0c;进制转换工具。 教程来自&#xff1a;阿西拜编程 QT C 5.9 3.记录 设置进制的第二种方法 ui->hex_tx->setDisplayIntegerBase(16); //设置显示进制为16进制 4.代码 widget.cpp #include "wi…

NOIP2018-S-DAY1-3-赛道修建(洛谷P5021)的题解

目录 题目 原题描述&#xff1a; 题目描述 输入格式 输出格式 输入输出样例 主要思路&#xff1a; check&#xff1a; 真正的code: 原题描述&#xff1a; 题目描述 C 城将要举办一系列的赛车比赛。在比赛前&#xff0c;需要在城内修建 条赛道。 C 城一共有 个路…

天梯赛的赛场安排(Python)

作者 陈越 单位 浙江大学 天梯赛使用 OMS 监考系统&#xff0c;需要将参赛队员安排到系统中的虚拟赛场里&#xff0c;并为每个赛场分配一位监考老师。每位监考老师需要联系自己赛场内队员对应的教练们&#xff0c;以便发放比赛账号。为了尽可能减少教练和监考的沟通负担&#…

打造私人云笔记,创造舒适的写作空间

搭建Minio 图片文件服务器 &#xff08;树莓派4B搭建Minio公网云服务器用nps内网穿透&#xff09;Typora 安装客户端 --> 可以利用免费gitee管理文档利用Typora 图像自定义文件上传功能 Minio强大的API功能 一、树莓派4B 64bit raspberry 操作系统 Docker Minio 图片文件…

CentOS本地部署Tale博客并结合内网穿透实现公网访问本地网站

文章目录 前言1. Tale网站搭建1.1 检查本地环境1.2 部署Tale个人博客系统1.3 启动Tale服务1.4 访问博客地址 2. Linux安装Cpolar内网穿透3. 创建Tale博客公网地址4. 使用公网地址访问Tale 前言 今天给大家带来一款基于 Java 语言的轻量级博客开源项目——Tale&#xff0c;Tale…

Python 配置信息的添加和获取

1.效果如下&#xff1a; 2.代码如下&#xff1a; from configparser import ConfigParser import threadingclass Config():_instance_lock threading.Lock()classmethoddef instance(cls, *args, **kwargs):if not hasattr(Config, "_instance"):with Config._ins…

ELK 基本操作

文章目录 1.Elasticsearch-head2.Kibana2.1.功能简介2.2.Management2.3.Discover2.4.Dev Tools 开源中间件 # Elastic Stackhttps://iothub.org.cn/docs/middleware/ https://iothub.org.cn/docs/middleware/elk/elk-use/1.Elasticsearch-head 2.Kibana 2.1.功能简介 2.2.Man…

电脑桌面便签下载,电脑桌面便签软件哪个好

电脑桌面便签下载&#xff0c;电脑桌面便签软件哪个好&#xff1f;在日常工作生活中&#xff0c;我们经常会遇到许多琐碎的事情需要记录和安排&#xff0c;这时候电脑桌面便签就成为了一个不可或缺的工具。而如今&#xff0c;在电脑时代的今天&#xff0c;电脑桌面便签软件更是…

扭蛋机小程序,扭蛋与互联网结合下的商机

扭蛋机作为一种娱乐消费模式&#xff0c;受众群体不再局限于儿童&#xff0c;也吸引了众多的年轻消费者。扭蛋机具有较大的随机性&#xff0c;玩具商品随机掉落&#xff0c;在购买前消费者完全不知道扭蛋中的商品是什么&#xff0c;这种未知性带来的惊喜感是吸引众多消费者的主…