提供五屏网站建设,网上网站开发,网站建设维护职责,网站策划教程相关历史文章(阅读本文前#xff0c;您可能需要先看下之前的系列?)国内最全的Spring Boot系列之三2020上半年发文汇总「值得收藏」GraphQL的探索之路 – SpringBoot集成GraphQL小栗子篇二 - 第315篇GraphQL的探索之路 – SpringBoot集成GraphQL之Query篇三 - 第316篇GraphQL的… 相关历史文章(阅读本文前您可能需要先看下之前的系列?)国内最全的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 查看偏高的进程老鼠爱上猫百度谷歌啊 查问题也是程序员必备技能之一莫欺少年穷要相信你肯定不是第一个遇到这个问题的愿得一人心查了不顶用。 问问题真的把问题说清楚不然解答的人也是一脸懵逼很多人都是愿意解答问题的但是问问题的人问的模棱两可导致没有人敢解答。正文开始 悟纤师傅师傅紧急求助。师傅徒儿何事如此之着急悟纤我发现我写的代码导致CPU持续为99%但是项目路这么大我也不知道是哪块代码导致的。师傅徒儿那你得看看是哪个线程里的逻辑导致了CPU飙高。悟纤那我们怎么找到这个线程在运行的堆栈信息呐师傅jstack呀你难道没有听过嘛悟纤知道到知道这个指令但是查看了些资料都是说的不清楚看完我也是一塌糊涂呐。师傅看来得为师给你好好讲讲了。悟纤还是喜欢师傅的讲解方式简单、详细、一语道破天机。一、排查步骤师傅要找回线程的堆栈信息主要是利用java给我们提供的调优工具jstack我们看下具体的一个步骤(1)使用命令top -p 显示你的java进程的cpu情况pid是你的java进程号比如14203。(使用jps可以获取到java的进程id 或者top直接查看)(2)按H获取每个线程的CPU情况。(shirtH)(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放到这里面。执行classjava com.kfit.jvm.EndlessLoopTest2.2 排查实战2.2.1 使用top找到cpu飙高的java进程ID 首先我们需要找到java进程ID使用top指令#top 我们一看就看到了pid为14203的java的CPU使用率是99.7%并且持续飙高那么这个肯定是代码写的有问题了。2.2.2 使用top -p 显示进程情况 我们使用如下命名查看java进程的情况#top -p 14203 通过-p的方法就是只显示了指定进程的信息。2.2.3 按H查看线程的CPU情况 在上面的界面中使用shirtH进行查看各个线程的CPU情况 注意这里的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方式三Linux/Mac的echo Echo也是很强大的echo ibase10;obase16;14204|bc方式四python的hex 利用python的转换hex将十进制转换为十六进制悟纤师傅你这是要飘了要跑题了。师傅哈哈师傅这是已经超神了。2.2.5 执行jstack得到线程的堆栈信息执行 jstack | grep -A 10 得到线程堆栈信息#jstack 14203 | grep -A 10 377c注意小c、小c、小c重要的事情说3遍。2.2.6查看对应的堆栈信息问题排查 我上面的堆栈信息可以看出出现问题的类是EndlessLoopTest.java代码行号是13源码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 i0;i5000;i){ test.test(); } }} 我们分析这个while循环看着挺正常的但是如果当random为0的时候不就是陷入死循环了吗。悟纤小结悟纤师傅你真是我的偶像讲解的如此之详细我要是再不懂看来只能退出编程界了。师傅徒儿言重了。虽然为师已经介绍的很详细了但是难免在实际使用的时候会踩到一些坑。悟纤那为了避免大家采坑我和大家总结下。核心就是两大步骤(1)通过top找到线程id。通过Linux系统的top命名找到cpu飙高的进程id通过top -p 找到该进程id的cpu信息然后配合shirtH命名就可以找到CPU线程高的线程ID通过工具类将十进制的线程id转换为十六进制的。(2)通过jstack找到线程的堆栈信息。 通过jstack | grep -A 10 就可以找到线程的堆栈信息。通过top找到线程id通过jstack找到线程的堆栈信息。我就是我是颜色不一样的烟火。我就是我是与众不同的小苹果。à悟空学院https://t.cn/Rg3fKJD学院中有Spring Boot相关的课程点击「阅读原文」进行查看SpringBoot视频http://t.cn/A6ZagYTiSpring Cloud视频http://t.cn/A6ZagxSRSpringBoot Shiro视频http://t.cn/A6Zag7IVSpringBoot交流平台https://t.cn/R3QDhU0SpringData和JPA视频http://t.cn/A6Zad1OHSpringSecurity5.0视频http://t.cn/A6ZadMBeSharding-JDBC分库分表实战http://t.cn/A6ZarrqS分布式事务解决方案「手写代码」http://t.cn/A6ZaBnIr深入理解JVM内存模型/调优实战http://t.cn/A6wWMVqG