IIWAB Java 内存分析工具 Arthas - IIWAB

Java 内存分析工具 Arthas

IIWAB 7小时前 ⋅ 7 阅读

一、概述

Arthas(阿尔萨斯)是阿里巴巴开源的一款Java诊断工具,用于实时检测、诊断Java应用程序的性能问题。它是一个命令行工具,提供了丰富的功能,包括查看类加载信息、方法执行耗时、线程堆栈、内存分析等 。Arthas的设计目标是在生产环境中实时诊断和解决Java应用程序的问题。

以下是 Arthas 的一些主要特点和功能:

  • 实时性:Arthas 可以在运行中的 Java 进程中实时进行诊断,无需重新启动应用。
  • 丰富的命令:提供了众多的命令,涵盖了类加载、方法执行、线程、内存、GC 等多个方面。
  • 动态追踪:支持实时动态追踪方法调用、线程堆栈等信息,方便定位问题。
  • 内存分析:提供了 Heap DumpHistogramClassloader Stats 等命令,帮助进行内存分析。
  • 多种环境支持:支持 LinuxMacWindows 操作系统,支持 HotSpotOpenJ9 JVM
  • 在线帮助:提供了丰富的在线帮助,用户可以通过 help 命令查看每个命令的详细说明。

请注意,Arthas 的使用可能需要一些对 Java 应用程序的基本了解。在生产环境中使用 Arthas 时,需要谨慎操作,以免对应用程序产生影响。详细的使用方法和命令说明可以参考 Arthas 的官方文档:

  • arthas.aliyun.com/doc/
  • github.com/alibaba/art…。

二、Arthas 安装

全量安装

wget https://arthas.aliyun.com/download/latest_version?mirror=aliyun -O arthas-packaging-3.7.1-bin.zip

unzip arthas-packaging-3.7.1-bin.zip
[root@local-168-182-110 arthas]#l
total 32060
-rw-r--r-- 1 root root -rw-r--r-- 1 root root -rw-r--r-- 1 root root 142141 Sep 27 2020 arthas-boot.jar 430937 Sep 27 2020 arthas-client.jar 8087 Sep 27 2020 arthas-agent.jar
drwxr-xr-x 2 root root -rw-r--r-- 1 root root 13460738 Sep 27 2020 arthas-core.jar 6 Dec 3 15:14 arthas-output
-rw-r--r-- 1 root root 18702021 Aug 24 21:17 arthas-packaging-3.7.1-bin.zip
-rw-r--r-- 1 root root 531 Sep 27 2020 arthas.properties
-rw-r--r-- 1 root root -rwxr-xr-x 1 root root 5074 Sep 27 3117 Sep 27 2020 arthas-spy.jar 2020 as.bat
-rwxr-xr-x 1 root root 7744 Sep 27 2020 as-service.bat
-rwxr-xr-x 1 root root 33931 Sep 27 2020 as.sh
drwxr-xr-x 2 root root -rwxr-xr-x 1 root root drwxr-xr-x 2 root root -rw-r--r-- 1 root root 2020 Sep 27 635 Sep 27 2020 install-local.sh 199 Sep 27 2020 async-profiler 146 Sep 27 2020 lib 2020 logback.xmU
-rw-r--r-- 1 root root [root@local-168-182-110 arthas]# [root@local-168-182-110 arthas]# 4121 Sep 27 2020 math-game.jar

三、Arthas 主要组成结构

主要有以下几大组件:

  • arthas-core.jar 是服务器端的启动入口类,调用 VirtualMachine#attach 到目标进程,并加载 arthas-agent.jar 作为 agent 包。
  • arthas-agent.jar 既可以使用 premain 方式(在目标进程启动之前,通过-agent 参数静态指定),也可以通过 agentmain 方式(在进程启动之后 attach上去)。arthas-agent会使用自定义的 classloader(ArthasClassLoader)加载 arthas-core.jar里面的Configure类以及ArthasBootstrap。 同时程序运行的时候会使用arthas-spy.jar
  • arthas-spy.jar 里面只包含Spy类,目的是为了将Spy类使用 BootstrapClassLoader来加载,从而使目标进程的java应用可以访问Spy类。通过ASM修改字节码,可以将Spy类的方法 ON_BEFORE_METHODON_RETURN_METHOD等编织到目标类里面。
  • arthas-client.jar 是客户端程序,用来连接arthas-core.jar启动的服务端代码,使用telnet方式。一般由arthas-boot.jaras.sh 来负责启动。

四、Arthas 通信主要流程

Arthas 应用是基于C/S的通信架构来设计的,支持 TelnetHttp 的客户端协议通信。

在服务器端的启动过程中会调用 ArthasBootstrap#bind 中, 会启动 TelnetHttp 通信协议的服务器实例并接收请求。

服务器端接收到客户端连接后都会为每个连接生成会话窗口,并会将发过来的请求内容解析后生成命令交由任务控制去完成响应。

其中每个客户端通信都对应唯一的 ShellImpl 实现,里面包括了唯一的 Session 实例,并持有 JobControllerImplInternalCommandManager 对象用于组装出异步任务去执行这个命令。

InternalCommandManager 类记录了所有命令,通过名字可搜索到对应的命令实现类,这里Command类会被包装 AnnotatedCommand 类放入列表中。

五、Arthas 快速入门讲解

1)启动 Arthas

# 第一重方式
./as.sh

# 第二种方式(推荐)
java -jar arthas-boot.jar
[root@local-168-182-110 arthas]# [root@local-168-182-110 arthas]#java -jar_arthas-boot.jar [INF0] JAVA HOME:/opt/jdk1.8.0 212/jre进性骊 [INF0] arthas-boot vers ton:3.7.1 [INF0] Found existing java process, please choose one and input the serial number of the process, eg :1. Then hit ENTER. [1]:99095 org.apache.zookeeper.server.quorum.QuorumPeerMain 1 输入进程编号 [INF0] arthas home:/opt/arthas [INFO] The target process already listen port 3658, skip attach.
[INFo] arthas-client conect 127.0.0.13658
ARTHAS wiki https://arthas.aliyun.com/doc tutorials https://arthas. aliyun.com/doc/arthas-tutorials.html 3.7.1 vers ion main_class pid 99095 time
2023-12-03 15:14:29
[arthas@99095]$

2)基础命令介绍

# 启动服务
java -jar arthas-boot.jar
# 查看帮助
help 
  • base64 :base64 编码转换,和 linux 里的 base64 命令类似
  • cat :打印文件内容,和 linux 里的 cat 命令类似
  • cls:清空当前屏幕区域
  • echo :打印参数,和 linux 里的 echo 命令类似
  • grep :匹配查找,和 linux 里的 grep 命令类似
  • help:查看命令帮助信息
  • history:打印命令历史
  • keymap :Arthas 快捷键列表及自定义快捷键
  • pwd :返回当前的工作目录,和 linux 命令类似
  • quit :退出当前 Arthas 客户端,其他 Arthas 客户端不受影响
  • reset :重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类
  • session:查看当前会话的信息
  • stop :关闭 Arthas 服务端,所有 Arthas 客户端全部退出
  • tee : 复制标准输入到标准输出和指定的文件,和 linux 里的 tee 命令类似
  • version :输出当前目标 Java 进程所加载的 Arthas 版本号

3)jvm 相关

# 启动服务
java -jar arthas-boot.jar
# 查看帮助
help 
  • dashboard:当前系统的实时数据面板
  • getstatic:查看类的静态属性
  • heapdump :dump java heap, 类似 jmap 命令的 heap dump 功能
  • jvm:查看当前 JVM 的信息
  • logger:查看和修改 logger
  • mbean:查看 Mbean 的信息
  • memory:查看 JVM 的内存信息
  • ognl:执行 ognl 表达式
  • perfcounter :查看当前 JVM 的 Perf Counter 信息
  • sysenv:查看 JVM 的环境变量
  • sysprop:查看和修改 JVM 的系统属性
  • thread:查看当前 JVM 的线程堆栈信息
  • vmoption :查看和修改 JVM 里诊断相关的 option
  • vmtool :从 jvm 里查询对象,执行 forceGc

1、dashboard(实时数据面板)

dashboard
ID -1 -1 -1 -1 48 19 45 46 -1 47 -1 13 31 14
NAME GROUP PRIORITY STATE %CPU DELTA_TIME TIME INTERRUPTE DAEMON
C2 CompilerThread0 15.2 0.760 0:3.273 false true
C2 CompilerThread2 -1 6.26 0.313 0:2.939 false true
C2 CompilerThread1 -1 4.17 0.208 0:3.356 false true
C1 CompilerThread3 -1 2.4 0.120 0:1.449 false true
Timer-for-arthas-dashboard-7b1 system 5 RUNNABLE 0.63 0.031 0:0.097 false true
scheduling-1 main 5 TIMED_WAI 0.62 0.031 0:0.097 false false
arthas-NettyHttpTelnetBootstra system 5 RUNNABLE0.35 0.017 0:0.097 false true
arthas-NettyHttpTelnetBootstra system 5 RUNNABLE 0.12 0.006 0:0.053 false true
VM Periodic Task Thread Thread -1 0.06 0.003 0:0.025 false true
arthas-command-execute system 5 TIMED_WAI 0.05 0.002 0:0.178 false true
VM Thread -1 0.03 0.001 0:0.105 false true
Catalina-utility-1 main 1 TIMED_WAI 0.01 0.000 0:0.005 false false
http-nio-8080-ClientPoller main 5 RUNNABLE0.0 0.000 0:0.002 false true
Catalina-utility-2 main 1 WAITING 0.0 0.000 0:0.004 false false
Memory used total max usage GC
heap 208M 393M 3641M 5.72% gc.ps_scavenge.count 7
ps_eden_space 197M 253M 1351M 14.60% gc.ps_scavenge. time(ms) 33
ps_survivor_space code_cache ps_old_gen nonheap Memory 68M OK 13M 11M 13M 134M 6656K 71M 2731M -1 240M 6656K 96.15% 0.41% 0.00% 5.75% gc.ps_marksweep. time(ms) gc.ps_marksweep.count GC 79 2
metaspace 48M 50M -1 95.56%
Runtime os.name os.version java.version java.home systemload.average processors
Mac OS X 10.15.4
Runtime
1.8.0_151 /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/H ome/jre 2.48 8

数据说明:

  • ID :Java级别的线程ID,注意这个ID不能跟jstack中的nativeID 一一对应
  • NAME:线程名
  • GROUP:线程组名
  • PRIORITY:线程优先级, 1~10 之间的数字,越大表示优先级越高
  • STATE:线程的状态
  • CPU%:线程消耗的cpu占比,采样 100ms ,将所有线程在这100ms内的cpu使用量求和,再算出每个线程的cpu使用占比。
  • TIME :线程运行总时间,数据格式为分:秒
  • INTERRUPTED:线程当前的中断位状态
  • DAEMON:是否是daemon线程

GC区域说明:

  • gc.ps_scavenge.count :从应用程序启动到当前采样时间年轻代gc次数
  • gc.ps_scavenge.time(ms) :从应用程序启动到当前采样时间年轻代gc所用的总时间(毫秒)
  • gc.ps_marksweep.count :从应用程序启动到当前采样时间老年代gc次数
  • gc.ps_marksweep.time(ms) :从应用程序启动到当前采样时间老年代gc所用的总时间(毫秒)

Memory 区域主要参数说明:

  • heap :堆内存使用情况(ps_eden_space+ps_survivor_space+ps_old_gen)
  • ps_eden_space:伊甸园区内存使用情况
  • ps_survivor_space :幸存区内存使用情况
  • ps_old_gen :老年代内存使用情况
  • nonheap:非堆内存使用情况

输入 q 或者 Ctrl+C 可以退出dashboard命令

2、Thread(线程相关堆栈信息)

参数说明:

  • 数字:线程id
  • [n:]:指定最忙的前N个线程并打印堆栈
  • [b]:找出当前阻塞其他线程的线程
  • [i ] :指定cpu占比统计的采样间隔,单位为毫秒

Arthas支持管道,可以用 thread 1 | grep 'main('<代码结束> 查找到main class` 。

thread 1 | grep 'main('

thread				#	显示所有线程的信息
thread 1			#	显示1号线程的运行堆栈
thread -b			#	查看阻塞的线程信息
thread -n 3			#	查看最忙的3个线程,并打印堆栈
thread -i 1000 -n 3	#	指定采样时间间隔,每过1000毫秒采样,显示最占时间的3个线程

# 查看处于等待状态的线程(WAITING、BLOCKED)
thread --state WAITING
[arthas@99095]$ thread 74 "arthas-NettyHttpTelnetBootstrap-3-6" Id=74 RUNNABLE (in native) at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269) at sun.nio.ch.EPollSelectorImpl. doSelect(EPollSelectorImpl. java:93) at sun.nio.ch.Selector Impl. lockAndDoSelect(SelectorImpl.java:86) at sun.nio.ch.Selector Impl.select(SelectorImpl.java:97) at sun.nio.ch.SelectorImpl.select(SelectorImpl. java:101) at com.al ibaba. arthas. deps. io.netty.channel.nto. SelectedSelect ionkeySetSelector.select(SelectedSelect ionkeySetSelector.java:68) at com.al ibaba.arthas.deps. io.netty.channel.nio

全部评论: 0

    我有话说: