原文链接:

00 本文简介

作为一名搞技术的程序猿或者是攻城狮,想必你应该是对下面这两个问题有所了解,说不定你在实际的工作或者面试就有遇到过:

第一个问题:Java死锁如何排查和解决?

第二个问题:服务器CPU占用率高达到100%排查和解决?

第三个问题:有哪些工具能够快速查看线程使用情况?

本文对这三个问题进行总结整理,通过实例演示讲解,精彩干货,不容错过啊!

前戏就这么多,高潮会很多,做好了,让我们直奔主题,发动小船,Let's go

01 Java死锁排查和解决

要排查和解决死锁,首先思考三个问题:

1. 什么是死锁?

2. 为什么会出现死锁?

3. 怎么排查代码中出现了死锁?

4. 如何避免写出死锁的代码?

作为技术人员(工程师),在出现问题的时候,能够尽快的去解决这个问题。但是在学习技术知识的时候,还是脚踏实地,多问一些为什么,一个好的问题,能够让自己思考,这方面的能力也一定要锻炼锻炼哦,这样才能更好的理解和掌握知识,并探究/触碰到更深入的地方。

1、啥是死锁?

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。[百度百科:死锁]

注:进程和线程都可以发生死锁,只要满足死锁的条件!

2、为啥子会出现死锁?

从上面的概念中我们知道

(1)必须是两个或者两个以上进程(线程)

(2)必须有竞争资源

3、怎么排查代码中出现了死锁?【重点来了】

首先整一个死锁的代码,看例子:

上面这段代码执行后,就会出现死锁,排查的姿势有如下几种,搞起来吧!

第一个姿势:使用 jps + jstack

:在windons命令窗口,使用jps -l【不会使用jps请自行查询资料】

:使用 jstack -l 12316 【不会使用jstack请自行查询资料】

第二个姿势:使用jconsole

在window打开 JConsole,JConsole是一个图形化的监控工具!

:在windons命令窗口 ,输出JConsole,如下图:

:选择到线程的tab上,如下截图。

第三个姿势:使用Java Visual VM

在window打开 jvisualvm,jvisualvm是一个图形化的监控工具!

:在windons命令窗口 ,输出 jvisualvm

:依然是切换到线程这个TAB上,很明显的就有提示!

4、如何避免死锁?

上面说了死锁出现的原因以及通过三种方式来检测和排查死锁,下面更重要的东西来了,就是如何避免死锁,如果能够让写出的代码避免死锁出现也就没有上面这些排查的过程了。最好的是从源头控制问题,而不是后期遇到问题在去填坑。

我看了阿里巴巴中最新的开发规约,里面有对避免死锁的说明,具体如下:

 

【强制】对多个资源、数据库表、对象同时加锁时,需要保持一致的加锁顺序,否则可能会 造成死锁。说明:线程一需要对表 A、B、C 依次全部加锁后才可以进行更新操作,那么线程二的加锁顺序也必须是 A、B、C,否则可能出现死锁。

 

02、Java CPU 100% 排查技巧

第一个姿势,步骤有点多,难度四星

平时多积累一点,这样在遇到问题的时候就少句求人的话。如果在实际的开发中遇到CPU 100%问题,要怎么排查呢?如果你没有遇到过这个问题,请先自己思考10s,如果你遇到过,这个时候也正好可以在回顾一遍。

、 使用top命令查看cpu占用资源较高的PID

当前占用cup100% 的PID为3455。

、通过jps找到当前用户下的java程序PID

执行jps -l能够打印出所有的应用的PID,找到有一个PID和这个cpu使用100%一样的ID!!!就知道是哪一个服务了。知道了对应的服务,在接着后续的分析步骤。

、 使用 pidstat -p < PID > 1 3 -u -t

  • -p:指定进程号复制代码
  • -u:默认的参数,显示各个进程的cpu使用统计复制代码
  • -t:显示选择任务的线程的统计信息外的额外信息复制代码

、找到cpu占用较高的线程TID ,通过上图发现是 3467的TID占用cup较大

、 因为jstack命令输出文件记录的线程ID是16进制。因此我们先将TID转换为十六进制的表示方式,转换方式可以参考下图。

3467转为十六进制 d8d,注意是小写!! 记录下来,后面会使用。

、通过jstack [-l] PID输出当前进程的线程信息

jstack PID  /temp/test.log复制代码

、查找 TID对应的线程(输出的线程id为十六进制),找到对应的代码,使用命令查找哦,不要肉眼比对,具体命令请思考,给你表现机会。

找到之后具体分析这个线程在干什么,为什么会占用这么多的 CUP资源。

PS:线程的几种状态如下说明:

  1. NEW,未启动的。不会出现在Dump中。
  2. RUNNABLE,在虚拟机内执行的。
  3. BLOCKED,受阻塞并等待监视器锁。
  4. WATING,无限期等待另一个线程执行特定操作。
  5. TIMED_WATING,有时限的等待另一个线程的特定操作。
  6. TERMINATED,已退出的。

第二个姿势,待开发[奸笑脸]

此处省略......,好多字。

03 推荐两个高效排查问题工具

show-busy-java-threads

官网地址:show-busy-java-threads[1]:https://github.com/oldratlee/useful-scripts/blob/master/docs/java.md#-show-busy-java-threads

简单安装和使用过程:

1.下载 show-busy-java-threads[2]2.上传服务器,然后进行解压3.然后执行对应的命令

:阿里开源的问题定位神器 arthas 来定位问题。

官网地址:arthas[3] :https://alibaba.github.io/arthas/index.html

这个里面有很多命令,如thread 支持一键展示当前最忙的前N个线程并打印堆栈,最简单的 thread -n 10 即可将最忙碌的十个线程快照打印出来,真正高效。

定位神器 arthas 安装过程就做介绍了,如果你还没有用过这个工具,我建议一定去用一下,说不定你会爱上它!

04 总结

本文内容比较多,基本上是手把手的教程了,希望能够对你有所帮助,也建议没有遇到类似问题的伙伴,看完之后一定要亲自去实践一下操作过程(有些姿势光看不用是不行的),如果没有环境可以自行想办法搞一个测试例子。还是老话:不要眼高手低,看了和做了本质上两个概念,最终收获的也一定不同。

05 彩蛋-另一个姿势

也可以通过使用jstack找到系统的代码性能问题

1、在进行压力测试的时候,使用jps找到应用的PID

2、然后使用jstack输出出压力测试时候应用的dump信息

3、分析输出的日志文件中那个方法block线程占用最多,这里可能是性能有问题,找到对应的代码分析

【性能优化】一文学会Java死锁和CPU100%问题的排查技巧的更多相关文章

  1. 一文学会Java死锁和CPU 100% 问题的排查技巧

    做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开 工欲善其事,必先利其器 00 本文简介 作为一名搞技术的程序猿或者是攻城狮,想必你应该是对下面这两个问题有所了解,说不定你在 ...

  2. 《Java程序性能优化:让你的Java程序更快、更稳定》

    Java程序性能优化:让你的Java程序更快.更稳定, 卓越网更便宜,不错的书吧

  3. JVM性能优化, Part 5 Java的伸缩性

    很多程序员在解决JVM性能问题的时候,花开了很多时间去调优应用程序级别的性能瓶颈,当你读完这本系列文章之后你会发现我可能更加系统地看待这类的问题.我说过JVM的自身技术限制了Java企业级应用的伸缩性 ...

  4. Java程序性能优化——让你的java程序更快、更稳定

    1.Java性能调优概述 1.1.Web服务器,响应时间.吞吐量是两个重要的性能参数. 1.2.程序性能的几个表现: 执行速度:程序的反映是否迅速,响应时间是否足够短 内存分配:分配是否合理,是否过多 ...

  5. 笔记《Java程序性能优化 让你的Java程序更快、更稳定》 第二章 设计调优

    2.1 善用设计模式 23 (1) 1. 设计模式好处: 2.1.1 单例模式 23 (6) 1. 单例模式是一种对象创建模式,用于产生一个对象的具体实例,它可以确保系统中一个类只产生一个实例: 2. ...

  6. 【Java技术专题】「性能优化系列」针对Java对象压缩及序列化技术的探索之路

    序列化和反序列化 序列化就是指把对象转换为字节码: 对象传递和保存时,保证对象的完整性和可传递性.把对象转换为有字节码,以便在网络上传输或保存在本地文件中: 反序列化就是指把字节码恢复为对象: 根据字 ...

  7. JS性能优化 之 文档片段 createDocumentFragment

    我们用原生JS进行开发时,经常会用到两种更新DOM节点的方法:innerHTML 和 appendChild() .其中 innerHTML 会完全替换掉原先的节点内容,如果我们是想向元素追加子节点的 ...

  8. 一文学会Java的交互式编程环境jshell

    什么是交互式编程环境?重点词交互,在这样的编程环境中,你每输入一行代码,环境都会给你一个反馈,这就是交互式的编程环境.这种编程环境并不太适合工程化的复杂性需求,但在一些快速验证.简单计算之类的场景下还 ...

  9. 一文学会Java事件机制

    本文同时发布于个人网站 https://ifuyao.com/blog/java-event/ 相信做 Java 开发的朋友,大多都是学习过或至少了解过 Java GUI 编程的,其中有大量的事件和控 ...

随机推荐

  1. FPM 1.1正式版 Search & List

    前面写的FPM都是自己练习用的.直到自己正式用了一个,才发现一些小问题.feeder class写在一起和分开写有好有坏,这里就不说了. 自己做了个小的查询报表如下: 现在来按SAP官方的做法来重新做 ...

  2. 【团队项目1】 团队展示&选题

    一.团队展示 1. 队名:这次稳了 2. 队员: 莫少政 3117004667 (队长) 黄思扬 3117004657 余泽端 3117004679 江海灵 3117004658 温治乾 311700 ...

  3. SqlServer数据库优化之索引、临时表

    问题:工作是查询一张500万多条数据的表时,查询总是很慢,于是进行优化. --查询表所有索引 use RYTreasureDB EXEC Sp_helpindex [RecordDrawScore] ...

  4. Django框架(十二)-- Djang与Ajax

    一.什么是Ajax AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”.即使用Javascript语言与服务器进行异步交互,传 ...

  5. python安装第三方库--换镜像源

    python安装第三方库--换镜像源 1. 更换anaconda源 清华大学镜像:清华大学镜像 anaconda下载地址:https://mirrors.tuna.tsinghua.edu.cn/an ...

  6. JDK1.8 LocalDate 使用方式;LocalDate 封装Util,LocalDate工具类(二)

    未完待续 ........ java.time.*代替方案 1.Instant 代替 Date2.LocalDateTime 代替 Calendar3.DateTimeFormatter 代替 Sim ...

  7. python基础语法18 类的内置方法(魔法方法),单例模式

    类的内置方法(魔法方法): 凡是在类内部定义,以__开头__结尾的方法,都是类的内置方法,也称之为魔法方法. 类的内置方法,会在某种条件满足下自动触发. 内置方法如下: __new__: 在__ini ...

  8. reactnative遇到的问题总结

    1.View中出现文本报错,View等标签中不能出现字符串文本,字符串文本需要包在Text中,遇到如下错误 下面是问题代码: let rightTitle = this.props.rightTitl ...

  9. 使用EventBus对模块解耦(附实例)

    用于模块间解耦,通过发布订阅的方式调用,每个人只负责自己的那部分. 写个小例子,比如现在有三个模块,订单.购物车.优惠券,由不同的人负责开发. 负责订单模块的人现在需要写个生成订单的方法,生成订单的逻 ...

  10. Scrapy笔记06- Item Pipeline

    Scrapy笔记06- Item Pipeline 当一个item被蜘蛛爬取到之后会被发送给Item Pipeline,然后多个组件按照顺序处理这个item. 每个Item Pipeline组件其实就 ...