timed_waiting线程是否占用cpu_程序CPU占用率飙升,如何定位线程的堆栈信息?超详细,值得收藏看不懂还有配套视频 第319篇...

关历史文章(阅读本文前,您可能需要先看下之前的系列?)

国内最全的Spring Boot系列之三

2020上半年发文汇总「值得收藏」

GraphQL的探索之路 – SpringBoot集成GraphQL小栗子篇二 - 第315篇

GraphQL的探索之路 – SpringBoot集成GraphQL之Query篇三 - 第316篇

GraphQL的探索之路 – SpringBoot集成GraphQL之Mutation篇四 - 第317篇

RocketMQ安装Linux/Mac/Window - 第318篇

需求缘起

在群里有这么一段对话:

愿得一人心:服务器cpu load偏高,无从下手,哪位大佬能提供点儿帮助

不老神话:top 查看偏高的进程

老鼠爱上猫:百度谷歌啊  查问题也是程序员必备技能之一

莫欺少年穷:要相信你肯定不是第一个遇到这个问题的

愿得一人心:查了,不顶用。

       问问题真的把问题说清楚,不然解答的人也是一脸懵逼,很多人都是愿意解答问题的,但是问问题的人问的模棱两可,导致没有人敢解答。

正文开始      

悟纤:师傅,师傅,紧急求助。

52322987efd58845fe606b7911d3f12a.gif

师傅:徒儿,何事如此之着急?

悟纤:我发现我写的代码导致CPU持续为99%,但是项目路这么大,我也不知道是哪块代码导致的。

师傅:徒儿,那你得看看是哪个线程里的逻辑导致了CPU飙高。

悟纤:那我们怎么找到这个线程在运行的堆栈信息呐?

师傅:jstack呀,你难道没有听过嘛?

悟纤:知道到知道这个指令,但是查看了些资料,都是说的不清楚,看完我也是一塌糊涂呐。

师傅:看来得为师给你好好讲讲了。

悟纤:还是喜欢师傅的讲解方式,简单、详细、一语道破天机

37639fde8052d687ea35d3d5760ecd61.gif

一、排查步骤

师傅:要找回线程的堆栈信息,主要是利用java给我们提供的调优工具jstack,我们看下具体的一个步骤:

(1)使用命令top -p ,显示你的java进程的cpu情况,pid是你的java进程号,比如14203。(使用jps可以获取到java的进程id 或者top直接查看)

(2)按H,获取每个线程的CPU情况。(shirt+H)

(3)找到内存和cpu占用最高的线程tid,比如14204。

(4)转为十六进制得到 377C ,此为线程id的十六进制表示。

(5)执行 jstack |grep -A 10 ,得到线程堆栈信息中1371这个线程所在行的后面10行。(注意:如果十六进制由字母的要小写)

# Jstack 14203 |  grep -A 10 377c

(6)查看对应的堆栈信息找出可能存在问题的代码。

师傅:看起来是不是很复杂,描述的罗里吧嗦的。

悟纤:看着就晕头转向的。

师傅:一句话概述。

一句话:通过top找到线程id,通过jstack找到线程的堆栈信息。

二、小试牛刀:Linux环境

2.1 准备工作

       我们编写一个小代码EndlessLoopTest用于模拟导致cpu过高(源码在最后提供),编译成class文件,将我们的class文件放到Linux上。

       注意:存放的需要根据包名建立目录结构,否则无法运行此class文件。

比如包名是com.kfit.jvm那么就需要创建一个目录结构com/kfit/jvm,然后把EndlessLoopTest.class放到这里面。

执行class:

java com.kfit.jvm.EndlessLoopTest

2.2 排查实战

2.2.1 使用top找到cpu飙高的java进程ID

       首先我们需要找到java进程ID,使用top指令:

#top

a4b33d97891c1c6b2b9965e402ac8163.png

       我们一看就看到了pid为14203的java的CPU使用率是99.7%并且持续飙高,那么这个肯定是代码写的有问题了。

2.2.2 使用top -p 显示进程情况

       我们使用如下命名查看java进程的情况:

#top -p 14203

1e7a4e64f69d2fa878547b56ead75ea1.png

       通过-p的方法就是只显示了指定进程的信息。

2.2.3 按H查看线程的CPU情况

       在上面的界面中使用shirt+H进行查看各个线程的CPU情况:

ae41e5f10166006eec5f4fed5dc7d2f2.png

       注意这里的PID实际对应的是线程的十进制的tid,通过上面我们可以看到CPU使用很高的线程ID是14204。

2.2.4 线程十进制转换为十六进制

       我们将获取到的线程十进制的转换为十六进制:

14204(十进制) = 377C(十六进制)

       怎么转你不知道嘛?

方式一:找个转换网站

https://tool.oschina.net/hexconvert/

https://tool.lu/hexconvert/(这个强大,可以一下子转换出来好几个进制的)

方式二:Linux/Mac的printf

       使用Linux/Mac的printf即可:

printf %x 14204  && echo

7c7c0560c7ddf8b3e01f9d69767d7696.png

方式三:Linux/Mac的echo

       Echo也是很强大的:

echo 'ibase=10;obase=16;14204'|bc

方式四:python的hex

       利用python的转换hex将十进制转换为十六进制:

d193cab96c757509ba769a9d8f0b8fc1.png

悟纤:师傅,你这是要飘了,要跑题了

556ec093fb812add815c33837e368d9e.png

师傅:哈哈,师傅这是已经超神了。

34b88e108349fb31c3336dc472ba060c.gif

2.2.5 执行jstack得到线程的堆栈信息

执行 jstack | grep -A 10 ,得到线程堆栈信息:

#jstack 14203 |  grep -A 10 377c

注意:小c、小c、小c,重要的事情说3遍。

6b41c214a4dcb195d27f5b17fcef6636.png

2.2.6查看对应的堆栈信息问题排查

       我上面的堆栈信息可以看出出现问题的类是EndlessLoopTest.java,代码行号是13:

a0d6bdc5590264c0fd4583778435fb13.png

源码:

package com.kfit.jvm;import java.net.Socket;/** * 死循环测试 */public class EndlessLoopTest {    public void test(){        int random = (int) (java.lang.Math.random() * 1000);        while (random < 100) {            random = random * 10;        }        System.out.println(random);    }    public static void main(String[] args) {        EndlessLoopTest test = new EndlessLoopTest();        for(int i=0;i<5000;i++){            test.test();        }    }}

       我们分析这个while循环,看着挺正常的,但是如果当random为0的时候,不就是陷入死循环了吗。

悟纤小结

悟纤:师傅,你真是我的偶像,讲解的如此之详细,我要是再不懂,看来只能退出编程界了。

师傅:徒儿,言重了。虽然为师已经介绍的很详细了,但是难免在实际使用的时候会踩到一些坑。

悟纤:那为了避免大家采坑,我和大家总结下。

核心就是两大步骤:

(1)通过top找到线程id。

通过Linux系统的top命名找到cpu飙高的进程id;通过top -p 找到该进程id的cpu信息;然后配合shirt+H命名,就可以找到CPU线程高的线程ID:通过工具类将十进制的线程id转换为十六进制的。

(2)通过jstack找到线程的堆栈信息。

       通过jstack | grep -A 10 就可以找到线程的堆栈信息。

通过top找到线程id,通过jstack找到线程的堆栈信息。

我就是我,是颜色不一样的烟火。
我就是我,是与众不同的小苹果。

à悟空学院:https://t.cn/Rg3fKJD

学院中有Spring Boot相关的课程!点击「阅读原文」进行查看!

SpringBoot视频:http://t.cn/A6ZagYTi

Spring Cloud视频:http://t.cn/A6ZagxSR

SpringBoot Shiro视频:http://t.cn/A6Zag7IV

SpringBoot交流平台:https://t.cn/R3QDhU0

SpringData和JPA视频:http://t.cn/A6Zad1OH

SpringSecurity5.0视频:http://t.cn/A6ZadMBe

Sharding-JDBC分库分表实战:

http://t.cn/A6ZarrqS

分布式事务解决方案「手写代码」:

http://t.cn/A6ZaBnIr

深入理解JVM内存模型/调优实战:

http://t.cn/A6wWMVqG

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

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

相关文章

图片的缩放(放大缩小)

package com.school.util;import java.awt.Graphics; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException;import javax.imageio.ImageIO; /*** * <b>类名称&#xff1a;图片处理工具类</b>ImageUtils…

sql多层嵌套别名无效_SQL之复杂查询

前文学了汇总分析&#xff0c;学了常见的汇总函数&#xff0c;会分组并且掌握了对分组结果指定条件。今天开始学习SQL的视图和子查询&#xff0c;还有数据库关联与嵌套查询内容的学习。一、视图1.1视图是有单固定存储可反复读取使用的子查询&#xff0c;所以视图适用于频繁使用…

POJ 1195 Mobile phones【 二维树状数组 】

题意&#xff1a;基础的二维数组&#xff0c;注意 0 lowbit(0)会陷入无限循环----- 之前做一道一维的一直tle,就是因为这个-------------------------- 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #includ…

mysql 交叉连接的用法_深入理解MySQL的外连接、内连接、交叉连接

1、内联接(典型的联接运算&#xff0c;使用像 或 <> 之类的比较运算符)。包括相等联接和自然联接。内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行。例如&#xff0c;检索 students和courses表中学生标识号相同的所有行。2、外联接。外联接可以是左向外联…

基于Angularjs实现分页

前言 学习任何一门语言前肯定是有业务需求来驱动你去学习它&#xff0c;当然ng也不例外&#xff0c;在学习ng前我第一个想做的demo就是基于ng实现分页&#xff0c;除去基本的计算思路外就是使用指令封装成一个插件&#xff0c;在需要分页的列表页面内直接引用。 插件 在封装分页…

mbot机器人初体验_[首发开箱]Makeblock mBot Ranger mBot游侠版 强大的STEM教育机器人...

本帖最后由 ahagowo 于 2016-4-17 08:38 编辑mBot游侠机器人套件是一个三种功能于一身的STEM教育机器人套件&#xff0c;它支持3种组装形态&#xff1a;机器人坦克&#xff0c;三轮赛车&#xff0c;和自平衡车。mBot游侠可通过 iPad&#xff0c;平板计算机或笔记本计算机来编程…

mysql数据库设计规范_MYSQL数据库设计规范与原则

MYSQL数据库设计规范1、数据库命名规范采用26个英文字母(区分大小写)和0-9的自然数(经常不需要)加上下划线_组成;命名简洁明确(长度不能超过30个字符);例如&#xff1a;user, stat, log, 也可以wifi_user, wifi_stat, wifi_log给数据库加个前缀;除非是备份数据库可以加0-9的自然…

jar乱放问题

之前看到一个项目不能继承类SimpleTagSuppert类&#xff0c;而将jsp-api.jar&#xff08;不知道servlet-api.jar能不能放&#xff09;放入到了 jdk/jre/lib/ext包下面结果不仅正在写的jsp不能运行&#xff0c;以前的web应用也不能运行&#xff0c;会出现 java.lang.ClassNotFo…

python课程笔记_Python课程笔记(一)

由于新冠状病毒的爆发&#xff0c;不得不在家里上网课&#xff0c;开课已经两个礼拜了&#xff0c;今天上完Python课后&#xff0c;准备整理一下最近学习Python的笔记。人生苦短&#xff0c;我用Python一、Hello World初学一门新的语言&#xff0c;就一定要从Hello World开始pr…

Bootstrap系列 -- 41. 带表单的导航条

有的导航条中会带有搜索表单,在Bootstrap框架中提供了一个“navbar-form”&#xff0c;使用方法很简单&#xff0c;在navbar容器中放置一个带有navbar-form类名的表单。navbar-left”让表单左浮动&#xff0c;更好实现对齐。在Bootstrap框架中&#xff0c;还提供了“navbar-rig…

mysql log table_mysqlbinlog功能扩展--table参数

目的mysqlbinlog在分析mysql的binlog日志时&#xff0c;有时需要针对某个表的操作进行分析。但是这个表属于“冷数据”&#xff0c;操作记录相对较少&#xff0c;而其他表操作往往很频繁&#xff0c;binlog日志量特别大。尤其是当binlog的模式设置为ROW时&#xff0c;情况就更加…

python递归迭代_Python入门基础知识点(python迭代器和递归)

函数名的使用&#xff1a;函数名是一个变量, 但它是一个特殊的变量, 与括号配合可以执行函数的变量函数名的内存地址&#xff1a;deffunc():passprint(func) #函数的内存地址结果&#xff1a;函数名可以赋值给其他变量&#xff1a;deffunc():print(1)afunca()func()#函数名可以…

怎么调处vs2010的MSDN帮助文档

如果装的是vs2010专业版的话 直接按F1直接可调出在线的帮助 直接按F2可以调出本机版的 转载于:https://www.cnblogs.com/fag888/p/5789159.html

redis的lrange_thinkphp5操作redis系列教程】列表类型之lRange,lGetRange

namespace app\admin\controller;use think\cache\driver\Redis;use think\Controller;use \think\Db;class Index extends Controller{//获取redispublic function getRedis(){$redis new \Redis();$redis->connect(127.0.0.1,6379);$redis->auth(root); //redis密码ec…

如何写好博客

好的博客是用来解决问题的&#xff0c;每一篇文章都应该以如何解决问题为驱动力&#xff0c;而不是知识点的累加&#xff0c;比如说之前写的[MVC]系列&#xff0c;均为知识点的堆积&#xff0c;没有例子和代码&#xff0c;也没有说明问题&#xff0c;这样的文章&#xff0c;基本…

云服务器建站原理_云服务器cvm与建站主机之间的区别

(文章来源&#xff1a;西部数码)云服务器cvm与建站主机区别是什么&#xff1f;cvm的英文全拼是CloudVirtualMachine(云虚拟机)&#xff0c;所以云服务器cvm是指虚拟云服务器&#xff0c;属于云服务器产品中的一种。而建站主机一般多是指虚拟主机&#xff0c;是在服务器中划分出…

Magento--判断checkout中是否使用了coupon code

在checkout页面中&#xff0c;如果想判断顾客是否有使用coupon code&#xff0c;可以通过checkout session来进行判断。以下代码会返回checkout中使用的coupon code或者返回空&#xff08;当没有使用coupon code时&#xff09; 1 <?php 2 3 $coupon_code Mage::getSingl…

启动python内核时发生错误_启动内核时出错

我一直看到这个消息。在An error ocurred while starting the kernelTraceback (most recent call last):File "C:\Users\Excel\Anaconda3\lib\runpy.py", line 193, in _run_module_as_main"__main__", mod_spec)File "C:\Users\Excel\Anaconda3\lib…

Scala笔记

1、伴生对象 形如&#xff1a; 有一个类 class Test{ } 一个object和该类同名 object Test{ } object Test的作用类似于静态类&#xff08;工具类&#xff09;&#xff0c;其中的所有成员都是静态的&#xff0c;在object Test中可以直接访问class Test的成员&#xff1b;…

maven找到mysql 连接池_在Tomcat6.0+MySQL5.0环境下配置和使用数据库连接池

一&#xff0c;在Tomcat中配置连接池的JNDI首先到MySQL的网站上下载MySQL JDBC连接器放到%CATALINA_HOME%/lib目录下&#xff0c;在%CATALINA_HOME%/conf目录下找到context.xml&#xff0c;这个文件是全局的&#xff0c;如果想只对特定的应用使用可以编辑WEB-INF/context.xml文…