JVM实战之性能调优[2](线程转储案例认识和分析)

文章目录

  • 版权声明
  • 案例1:CPU占用率高问题
    • 问题描述
    • 解决思路
    • 补充内容
  • 案例2:接口响应时间长问题
    • 问题描述
    • 解决思路
    • Arthas trace命令
    • Arthas watch命令
    • 解决问题
  • 案例3:定位偏底层性能问题
    • 问题描述
    • 解决思路:Arthas火焰图
    • 问题解决
  • 案例4:线程被耗尽问题
    • 问题描述
    • 解决思路
    • 问题解决
    • 死锁代码优化

版权声明

  • 本博客的内容基于我个人学习黑马程序员课程的学习笔记整理而成。我特此声明,所有版权属于黑马程序员或相关权利人所有。本博客的目的仅为个人学习和交流之用,并非商业用途。
  • 我在整理学习笔记的过程中尽力确保准确性,但无法保证内容的完整性和时效性。本博客的内容可能会随着时间的推移而过时或需要更新。
  • 若您是黑马程序员或相关权利人,如有任何侵犯版权的地方,请您及时联系我,我将立即予以删除或进行必要的修改。
  • 对于其他读者,请在阅读本博客内容时保持遵守相关法律法规和道德准则,谨慎参考,并自行承担因此产生的风险和责任。
  • 本博客中的部分观点和意见仅代表我个人,不代表黑马程序员的立场。
  • 由于作者精力有限,有关代码的演示和工具的使用和操作,请食用官方的B站JVM教程视频

案例1:CPU占用率高问题

问题描述

  • 监控人员通过prometheus的告警发现CPU占用率一直处于很高的情况,通过top命令看到是由于Java程序引起的,希望能快速定位导致性能问题的代码。

解决思路

  1. 通过top –c 命令找到CPU占用率高的进程,获取进程ID
    在这里插入图片描述
  2. 使用top -p 进程ID单独监控某个进程,按 H H H查看到所有的线程以及线程对应的CPU使用率,找到CPU使用率特别高的线程,并记录线程ID。
    在这里插入图片描述
  3. 使用 jstack 进程ID 命令可以查看到所有线程正在执行的栈信息。使用 jstack 进程ID > 文件名 保存到文件中方便查看。
    在这里插入图片描述
  4. 找到 n i d 线程 I D nid线程ID nid线程ID相同的栈信息,需要将之前记录下的十进制线程号转换成16进制。通过 p r i n t f ′ printf '%x\n' printf 线程ID 命令直接获得16进制下的线程ID
    在这里插入图片描述
  5. 找到栈信息对应的源代码,并分析问题产生原因

补充内容

  • 在定位CPU占用率高的问题时,需要关注的是状态为 R U N N A B L E RUNNABLE RUNNABLE的线程。但实际上,有一些线程执行本地方法时并不会消耗CPU,而只是在等待。但 JVM 仍然会将它们标识成“RUNNABLE”状态。
    在这里插入图片描述

案例2:接口响应时间长问题

问题描述

  • 程序运行过程中,发现有几个接口的响应时间特别长,需要快速定位执行过程中出现性能问题的代码。

解决思路

  • 确定出现性能问题的方法,借助于arthas定位到具体的方法(在方法嵌套比较深的情况下)
    在这里插入图片描述

Arthas trace命令

  • 使用arthas的trace命令,可以展示出整个方法的调用路径以及每一个方法的执行耗时。
  • 语法格式
    trace 类名 方法名
    

⚫ 添加--skipJDKMethod false 参数可以输出JDK核心包中的方法及耗时。
⚫ 添加 #cost > 毫秒值 参数,只会显示耗时超过该毫秒值的调用。
⚫ 添加 –n 数值 参数,最多显示该数值条数的数据。
⚫ 所有监控都结束之后,输入 s t o p stop stop结束监控,重置arthas增强的对象
在这里插入图片描述

Arthas watch命令

  • 使用trace定位到性能较低的方法后,使用watch命令监控该方法,可以获得更为详细的方法信息。
  • 语法格式
    watch 类名 方法名 ‘{params, returnObj}’ ‘#cost>毫秒值' -x 2
    
  • {params, returnObj} 代表打印参数和返回值。
  • -x 代表打印的结果中如果有嵌套(比如对象里有属性),最多只展开2层。允许设置的最大值为4。
    在这里插入图片描述

解决问题

  1. 通过arthas的trace命令,首先找到性能较差的具体方法,如果访问量比较大,建议设置最小的耗时,精确的找到耗时比较高的调用。
  2. 通过watch命令,查看此调用的参数和返回值,关注参数,在开发环境或者测试环境模拟现象,通过debug找到具体的问题根源。
  3. 使用stop命令将所有增强的对象恢复。

案例3:定位偏底层性能问题

问题描述

  • 接口中使用for循环向ArrayList中添加数据,但是最终发现执行时间比较长,需要定位是导致的性能低下的原因
@GetMapping("/profile1")
public void test6() throws InterruptedException {ArrayList<Integer> objects = new ArrayList<>();for (Integer i = 0; i < 20000000; i++) {objects.add(i);}
}

解决思路:Arthas火焰图

  • 使用Arthas提供性能火焰图的功能,查看方法的执行耗时
  • 使用arthas的profile命令,生成性能监控的火焰图
    profiler start #1 开始监控方法执行性能
    profiler stop --format html #2 以HTML的方式生成火焰图
    
  • 火焰图中一般找绿色部分Java中栈顶上比较平的部分,很可能就是性能的瓶颈
    在这里插入图片描述
  • 偏底层的性能问题,特别是由于JDK中某些方法被大量调用导致的性能低下,可以使用火焰图非常直观的找到原因

问题解决

  • 案例中是由于创建ArrayList时没有手动指定容量,导致使用默认的容量而在添加对象过程中发生了多次的扩容,扩容需要将原来数组中的元素复制到新的数组中,消耗了大量的时间。
  • 优化后的代码
@GetMapping("/profile2")public void test7() throws InterruptedException {ArrayList<Integer> objects = new ArrayList<>(20000000);for (Integer i = 0; i < 20000000; i++) {objects.add(i);}}

案例4:线程被耗尽问题

问题描述

  • 程序在启动运行一段时间之后,就无法接受任何请求。将程序重启之后继续运行,依然会出现相同的情况。

解决思路

  • 线程耗尽问题,一般是由于执行时间过长,分析方法分成两步:
    1. 检测是否有死锁产生,无法自动解除的死锁会将线程永远阻塞。
    2. 如果没有死锁,再使用案例1的打印线程栈的方法检测线程正在执行的方法,一般大量出现的方法就是慢方法。
  • 死锁:两个或以上的线程因为争夺资源而造成互相等待的现象

问题解决

线程死锁可以通过三种方法定位问题:

  1. jstack -l 进程ID > 文件名将线程栈保存到本地,在文件中搜索deadlock即可找到死锁位置
    在这里插入图片描述
  2. 开发环境中使用visual vm或者Jconsole工具,检测死锁。使用线程快照生成工具查看死锁的根源。生产环境的服务一般不会允许使用这两种工具连接。
    在这里插入图片描述
  3. 使用fastthread自动检测线程问题(Fastthread,是一款在线的AI自动线程问题检测工具,可以提供线程分析报告。通过报告查看是否存在死锁问题。)
    在这里插入图片描述

死锁代码优化

  • 问题代码
private Object obj1 = new Object();
private Object obj2 = new Object();
@GetMapping("/deadlock1")
public String test1() throws InterruptedException {synchronized (obj1){Thread.sleep(5000);synchronized (obj2){return "返回成功";}}
@GetMapping("/deadlock2")
public String test2() throws InterruptedException {synchronized (obj2){Thread.sleep(5000);synchronized (obj1){return "返回成功";}}    
  • 优化代码
private Object obj1 = new Object();
private Object obj2 = new Object();
private Lock lock1 = new ReentrantLock();
private Lock lock2 = new ReentrantLock();@GetMapping("/deadlock1")
public String test1() throws InterruptedException {boolean b1 = lock1.tryLock(1, TimeUnit.SECONDS);if(b1){try {Thread.sleep(5000);boolean b2 = lock2.tryLock(1, TimeUnit.SECONDS);if(b2){try{return "返回成功";}finally {lock2.unlock();}}}finally {lock1.unlock();}}return "处理失败";
}@GetMapping("/deadlock2")
public String test2() throws InterruptedException {boolean b1 = lock2.tryLock(1, TimeUnit.SECONDS);if(b1){try {Thread.sleep(5000);boolean b2 = lock1.tryLock(1, TimeUnit.SECONDS);if(b2){try{return "返回成功";}finally {lock1.unlock();}}}finally {lock2.unlock();}}return "处理失败";
}

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

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

相关文章

论文阅读,Accelerating the Lattice Boltzmann Method(五)

目录 一、Article:文献出处&#xff08;方便再次搜索&#xff09; &#xff08;1&#xff09;作者 &#xff08;2&#xff09;文献题目 &#xff08;3&#xff09;文献时间 &#xff08;4&#xff09;引用 二、Data:文献数据&#xff08;总结归纳&#xff0c;方便理解&am…

大话设计模式之原型模式

原型模式&#xff08;Prototype Pattern&#xff09;是一种创建型设计模式&#xff0c;它用于创建对象的复制&#xff0c;同时又能保持对象的封装。原型模式通过复制现有对象的方式来创建新的对象&#xff0c;而无需知道具体创建过程的细节。 在原型模式中&#xff0c;通常会有…

Windows系统搭建Oracle结合内网穿透实现公网访问本地数据库

文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址4.1 保留一个固定的公网TCP端口地址4.2 配置固定公网TCP端口地址4.3 测试使用固定TCP端口地址远程Oracle 前言 Oracle&#xff0c;是甲骨文公司的一款关系…

java ssh 电影院购票管理系统eclipse开发mysql数据库MVC模式java编程网页设计

一、源码特点 JSP ssh 电影院购票管理系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用 B/S模式开发。开发环境为TOMCAT…

C# 高级文件操作与异步编程探索(初步)

文章目录 文本文件的读写探秘StreamReader 类深度剖析StreamWriter 类细节解读编码和中文乱码的解决方案 二进制文件的读写BinaryReader 类全面解析BinaryWriter 类深度探讨 异步编程与C#的未来方向同步与异步&#xff1a;本质解读Task 的神奇所在async/await 的魔法 在现代编程…

推动制药行业数字化转型:基于超融合架构的MES一体机解决方案

随着中国对信息化重视程度的不断加深&#xff0c;制药行业作为国民经济的重要支柱之一&#xff0c;也在积极寻求通过数字化手段提升产业效率与产品质量。自党的十六大提出“以信息化带动工业化”的战略以来&#xff0c;制药业的这一转型探索尤为迫切。 在现代制药生产中&#…

【已修复】iPhone13 Pro 长焦相机水印(黑斑)修复 洗水印

iPhone13 Pro 长焦相机水印&#xff08;黑斑&#xff09;修复 洗水印 问题描述 iPhone13 Pro 后摄3倍相机有黑色斑点&#xff08;水印&#xff09;&#xff0c;如图所示&#xff0c; 后摄相机布局如图所示&#xff0c; 修复过程 拆机过程有风险&#xff0c;没有把握最好不要…

芒果YOLOv8改进145:全新风格原创YOLOv8网络结构解析图

&#x1f4a1;本篇分享一下个人绘制的原创全新风格 YOLOv8网络结构图 感觉搭配还行&#xff0c;看着比较直观。 该专栏完整目录链接&#xff1a; 芒果YOLOv8深度改进教程 订阅了专栏的读者 可以获取一份 <可以自行修改 / 编辑> 的 YOLOv8结构图修改源文件 YOLOv8结构图…

HackTheBox-Machines--Legacy

文章目录 1 端口扫描2 测试思路3 445端口漏洞测试4 flag Legacy 测试过程 1 端口扫描 nmap -sC -sV 10.129.227.1812 测试思路 目标开启了135、139、445端口&#xff0c;445 SMB服务存在很多可利用漏洞&#xff0c;所以测试点先从445端口开始。而且在Nmap扫描结果中&#xff0c…

项目四-图书管理系统

1.创建项目 流程与之前的项目一致&#xff0c;不再进行赘述。 2.需求定义 需求: 1. 登录: ⽤⼾输⼊账号,密码完成登录功能 2. 列表展⽰: 展⽰图书 3.前端界面测试 无法启动&#xff01;&#xff01;&#xff01;--->记得加入mysql相关操作记得在yml进行配置 配置后启动…

量化交易入门(二十五)什么是RSI,原理和炒股实操

前面我们了解了KDJ&#xff0c;MACD&#xff0c;MTM三个技术指标&#xff0c;也进行了回测&#xff0c;结果有好有坏&#xff0c;今天我们来学习第四个指标RSI。RSI指标全称是相对强弱指标(Relative Strength Index),是通过比较一段时期内的平均收盘涨数和平均收盘跌数来分析市…

3.28总结

1.java学习记录 1.方法的重载 重载换而言之其实就是函数名不变&#xff0c;但是其中的参数需要改变&#xff0c;可以三个方面改变&#xff08;参数类型&#xff0c;参数顺序&#xff0c;参数个数这三个方面入手&#xff0c;这样可以运用的&#xff09; 但是&#xff1a;注意…

2024.3.21|华北水利水电大学江淮校区ACM社团训练赛

2024.3.21|华北水利水电大学江淮校区ACM社团训练赛 1.数字拆解 2.矩阵修改 3.因子数 4.回文数 5.中位数 心有猛虎&#xff0c;细嗅蔷薇。你好朋友&#xff0c;这里是锅巴的C\C学习笔记&#xff0c;常言道&#xff0c;不积跬步无以至千里&#xff0c;希望有朝一日我们积累的滴…

springboot+vue在idea上面的使用小结

1.在mac上面删除java的jdk方法&#xff1a; sudo rm -rfjdk的路径 sudo rm -rf /Users/like/Library/Java/JavaVirtualMachines/corretto-17.0.10/Contents/Home 2.查询 Mac的jdk版本和路径&#xff1a; /usr/libexec/java_home -V 3.mac上面查询和关闭idea的网页端口&…

快速上手Spring Cloud五:Spring Cloud与持续集成/持续部署(CI/CD)

快速上手Spring Cloud 一&#xff1a;Spring Cloud 简介 快速上手Spring Cloud 二&#xff1a;核心组件解析 快速上手Spring Cloud 三&#xff1a;API网关深入探索与实战应用 快速上手Spring Cloud 四&#xff1a;微服务治理与安全 快速上手Spring Cloud 五&#xff1a;Spring …

samba实现linux共享文件夹

一、samba安装 sudo apt install samba 二、配置Samba 编辑Samba配置文件sudo vi /etc/samba/smb.conf 在文件末尾添加以下内容&#xff0c;设置一个简单的共享目录&#xff08;替换path_to_share为实际的共享目录路径&#xff09;&#xff1a; [Share] path /path_to_sha…

鱼眼相机的测距流程及误差分析[像素坐标系到空间一点以及测距和误差分析]

由于最近在整理单目测距的内容&#xff0c;顺手也总结下鱼眼相机的测距流程和误差分析&#xff0c;如果有错误&#xff0c;还请不吝赐教。 参考链接: 鱼眼镜头的成像原理到畸变矫正&#xff08;完整版&#xff09; 相机模型总结&#xff08;针孔、鱼眼、全景&#xff09; 三维…

Unity照片墙简易圆形交互效果总结

还要很多可以优化的点地方&#xff0c;有兴趣的可以做 比如对象的销毁和生成可以做成对象池&#xff0c;走到最左边后再移动到最右边循环利用 分析过程文件&#xff0c;采用Blender&#xff0c;资源已上传&#xff0c;可以播放动画看效果&#xff0c;下面截个图&#xff1a; …

关系型数据库mysql(8)sql高级语句②

目录 一.子查询——Subquery 语法 环境准备 In——查询已知的值的数据记录 子查询——Insert 子查询——Update 子查询——Delete Not In——表示否定&#xff0c;不在子查询的结果集里 Exists——判断查询结果集是否为空 子查询——别名 ​编辑 二.视图 理论&a…

图论之路径条数专题

一直忙着金工实习蓝桥杯&#xff0c;好久没有看图论了&#xff0c;今天就小试几题享受下被虐的快感。 1.最短路拓扑 首先来几个结论&#xff1a; 1.最短路图没有环&#xff08;可以用反证法证明&#xff09; 2.dis[u]edge[u,v]dis[v]&#xff0c;那么u,v端点的边一定在最短路…