Bootstrap

Java诊断工具-Arthas保姆级教程

目录

一.Arthas简介

1.简介

2.Arthas能解决哪些问题?

3.Arthas主要功能

二.Arthas的安装和使用

1.安装包

2.启动

3.进入对应的java进程

 4.交互界面的命令

三.生产实战

1.使用Arthas定位CPU飙升

 2.排查内存泄漏

 3.排查死锁问题

四.内存溢出分类


一.Arthas简介

1.简介

Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。支持JDK 6+,支持Linux/Mac/Winodws,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。

2.Arthas能解决哪些问题?

这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
是否有一个全局视角来查看系统的运行状况?
有什么办法可以监控到JVM的实时运行状态?

当你遇到以上类似问题而束手无策时,Arthas可以帮助你解决。

3.Arthas主要功能

(1) 信息监控
进程运行基本信息:内存、CPU占用、线程信息、线程堆栈、线程数统计、环境变量信息
对象信息:类对象静态属性、 Mbean 的属性信息、已加载类信息、类加载器、类方法信息
(2) 方法调用
方法调用入参、返回值查看
方法被调用的调用路径、调用耗时、方法调用次数、成功次数、失败次数等统计
记录和重做方法调用
(3) 类文件处理
dump已加载类的字节码、字节码反编译、类编译、类重新热加载

二.Arthas的安装和使用

1.安装包

小编这边 已经为各位大爷提供好了 arthas的下载链接:
链接:https://pan.baidu.com/s/1ZYv3hGyaHGCYZ-VL6WPbdg 
提取码:oruc

或者外网的机器可以直接通过命令下载

wget https://alibaba.github.io/arthas/arthas-boot.jar

下载下来解压后打开文件夹如下

2.启动

java -jar arthas-boot.jar

3.进入对应的java进程

输入进程对应编号,进入Arthas的命令交互界面即可使用

 4.交互界面的命令

(1)dashboard:展示当前系统的实时数据面板,按 ctrl+c 退出。

 (2)查看线程监控

输入thread命令,会显示所有线程的状态信息
输入thread -n 3会显示当前最忙的3个线程,可以用来排查线程CPU消耗
输入thread -b 会显示当前处于BLOCKED状态的线程,可以排查线程锁的问题

 (3)JVM监控

输入jvm命令,查看jvm详细的性能数据

 (4)观察方法参数、返回值(watch)

有时排查问题中我们需要查看参数,返回值,通常的需要加日志打印,比较繁琐,基于watch命令我们可以很方便做到这一切

(5)观察方法调用路径,耗时详情(trace)

有时会遇到服务卡顿,想排查到底哪个步骤耗时比较久,通常做法是加日志,使用trace命令可以很方便解决这个问题

以上提供一些主要的交互命令,具体请见官网

https://arthas.aliyun.com/doc/commands.html

三.生产实战

1.使用Arthas定位CPU飙升

thread

 2.排查内存泄漏

(1)命令排查

第一步:检查Full GC的情况

jstat -gc pid 间隔时间 显示次数

jps -l

jstat -gc 97598 3000 30

 第二步: 查看消耗CPU的线程

根据上面排查CPU的方法我们排查下那个线程消耗的CPU比较多,一般是FGC的垃圾回收线程,对FGC做一个佐证

top

查看消耗CPU比较高的线程

top -H -p 97598

 接下来将线程ID转换为对应的16进制进行排查

printf "%x" 97600
jstack 97598|grep 17d40 -A20

第三步:查看内存对象

 可以通过jmap导出dump转储文件,但是不推荐使用,导出的时候服务将会不响应请求,如果导出的文件很大,则可能造成服务长时间假死,可以使用jmap -histo pid来查看那些对象占用的内存大

# 列出来存活对象占用的内存大小,并且只显示前20行
jmap -histo:live 97598|head -20

 3.排查死锁问题

(1)命令行检查死锁(可以使用jstack快速进行死锁检查)

jps -l
jstack -l 100460|grep "deadlock"

 jstack -l 100460  导出堆栈信息,死锁信息就在最后

 (2)Arthas排查死锁

thread -b

找到死锁的线程id后就可以查看具体堆栈信息了

四.内存溢出分类

堆内存溢出
堆内存是存放由 new 创建的对象和数组,在堆中分配的内存,由 Java 虚拟机的自动垃圾回收器来管理 
异常类型:java.lang.OutOfMemoryError: Java heap space 
优化:通过-Xmn(最小值)–Xms(初始值) -Xmx(最大值)参数手动设置 Heap(堆)的大小

元空间溢出
元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存
异常类型:Java.Lang.OutOfMemoryError:Metaspace
优化:通过调整-XX:MaxMetaspaceSize设置元空间大小

栈溢出
栈内存在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配(更准确地说是保存了引用的堆内存空间的地址,java中的“指针”)
异常类型: java.lang.StackOverflowError 
优化:通过Xss参数调整

;