新闻资讯

新闻资讯 媒体报道

JDK调优工具

编辑:016     时间:2021-12-13
一、JDK 监控工具
1.1 jps: jvm进程状况工具
显示指定系统内的所有HotSpot进程,命令格式:
jps [option] [ hostid]
hostid为RMI注册表中注册的主机名

选项 作用
-q 值输出LVMID
-m 输出虚拟机进程启动的传递给main的参数
-l 输出主类全类名;若果时jar、war显示jar、war名称
-v 输出虚拟机进程启动时JVM参数
1.2 jstat:jvm统计信息监视工具
用于收集HotSpot个方面的运行数据,包括类装载、内存、垃圾回收、JIT等运行数据,在没有GUI界面,它将是jvm性能问题的首选项。

jstat [option vmid [interval[m|ms] [count] ] ]

如果是远程程序 vmid变成 [protocal:][//]vmid[@hostname[:port]/servername]

Option主要分为三类:1.类装载;2垃圾回收;3.运行期编译状况。

选项 作用
-class 监视类的装载、卸载数量、总空间以及类装载所好烦的时间
-gc 监视类Java堆状况,包括Eden区、两个survivor区, 看各个区域的使用大小
-gccapacity 显示各个代的容量以及使用情况;
-gcmetacapacity 显示metaspace的大小
-gcnew 显示新生代信息;
-gcnewcapacity 显示新生代大小和使用情况;
-gcold 显示老年代和永久代的信息;
-gcoldcapacity 显示老年代的大小;
-gcutil 显示垃圾收集信息, 看各个区域的使用百分比;
-gccause 显示垃圾回收的相关信息(通-gcutil),同时显示最后一次或当前正在发生的垃圾回收的诱因;
-printcompilation 输出JIT编译的方法信息;
C:\Program Files\Java\jdk1.8.0_181\bin>jstat -gc 15800
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
5120.0 5120.0  0.0   5097.8 33280.0  17026.3   87552.0     754.3    20992.0 20348.8 2560.0 2367.3      3    0.026   0      0.000    0.026
1.3 jinfo: java配置信息工具
jinfo -flags 2289 查看启动参数
显示jvm配置信息,+或- 配置jvm参数

1.4 jmap:java内存映象工具
用于生成堆转储快照,还可以参看finalize执行队列,java堆、永久代的详情,如空间使用率,哪种垃圾回收器等。

选项 作用
-dump 生成java堆转储快照
-finalizerinfo 等待F你那里责任线程执行finalizer方法的对象。只在Linux、Solaris有效
-heap 堆详情,如:使用哪种回收期、参数配置、分代等只在Linux、Solaris有效
-histo 显示在队中对象统计信息。包括类、实例数量、合计容量
-permstat ClassLoader为统计接口用接待内存状态只在Linux、Solaris有效
-F 强制输出dump快照。只在Linux、Solaris有效
jmap -dump:format=b,file=heap.hprof 31531
获得堆快照文件之后,我们可以使用多种工具对文件进行分析,例如jhat,visual vm等。

1.5 jhat:jvm堆转储快照分析工具
使用jhat工具可以分析Java应用程序的堆快照文件,使用命令如下:
jhat heap.hprof

jhat在分析完成之后,使用HTTP服务器展示其分析结果,在浏览器中访问http://127.0.0.1:7000/即可得到分析结果。

1.6 jstack : java堆栈跟踪工具
用于生成kvm当前线程的快照(threadtump或javacore工具)

选项 作用
F 强制输出线程堆栈
l 附加关于锁的信息
m 本地方法,可以显示c/c++堆栈
1.7 HSDIS: JIT代码生成反汇编
让HotSpot的-XX:+printAssembly指令调用它来把动态代码生成的本地代码还原成汇编输出。

1.8 jstatd命令
jstatd命令是一个RMI服务器程序,它的作用相当于代理服务器,建立本地计算机与远程监控工具的通信,jstatd服务器能够将本机的Java应用程序信息传递到远程计算机,由于需要多台计算机做演示,此处略。

1.9 hprof工具
hprof工具可以用于监控Java应用程序在运行时的CPU信息和堆信息,关于hprof的官方文档如下:https://docs.oracle.com/javase/7/docs/technotes/samples/hprof.html

2 jdk可视化工具
2.1 jconsole
2.2 VisualVM
2.3 MAT内存分析工具
MAT是一款功能强大的Java堆内存分析器,可以用于查找内存泄露以及查看内存消耗情况,MAT的官方文档如下:http://help.eclipse.org/luna/index.jsp?topic=/org.eclipse.mat.ui.help/welcome.html。

在MAT中有浅堆和深堆的概念,浅堆是指一个对象结构所占用的内存大小,深堆是指一个对象被GC回收后可以真正释放的内存大小。

通过MAT,可以列出所有垃圾回收的根对象,Java系统的根对象可能是以下类:系统类,线程,Java局部变量,本地栈等等。在MAT中还可以很清楚的看到根对象到当前对象的引用关系链。

MAT还可以自动检测内存泄露,单击菜单上的Leak Suspects命令,MAT会自动生成一份报告,这份报告罗列了系统内可能存在内存泄露的问题点。

在MAT中,还可以自动查找并显示消耗内存最多的几个对象,这些消耗大量内存的大对象往往是解决系统性能问题的关键所在。

3. Arthas - Java
官网:https://alibaba.github.io/arthas
强大功能:

是否有一个全局视角来查看系统的运行状况?
为什么 CPU 又升高了,到底是哪里占用了 CPU ? 运行的多线程有死锁吗?有阻塞吗?
程序运行耗时很长,是哪里耗时比较长呢?如何监测呢?
这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
有什么办法可以监控到 JVM 的实时运行状态?
3.1 下载与启动:
arthas-boot.jar,然后用java -jar的方式启动:

# 运行方式1,先运行,在选择 Java 进程 PID
java -jar arthas-boot.jar
# 选择进程(输入[]内编号(不是PID)回车)
[INFO] arthas-boot version: 3.1.4
[INFO] Found existing java process, please choose one and hit RETURN.
* [1]: 11616 com.Arthas
  [2]: 8676
  [3]: 16200 org.jetbrains.jps.cmdline.Launcher
  [4]: 21032 org.jetbrains.idea.maven.server.RemoteMavenServer


# 运行方式2,运行时选择 Java 进程 PID

java -jar arthas-boot.jar [PID]


3.2 常用命令
命令 作用
dashboard 当前系统的实时数据面板
thread 查看当前 JVM 的线程堆栈信息
watch 方法执行数据观测
trace 方法内部调用路径,并输出方法路径上的每个节点上耗时
stack 输出当前方法被调用的调用路径
tt 方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测
monitor 方法执行监控
jvm 查看当前 JVM 信息
vmoption 查看,更新 JVM 诊断相关的参数
sc 查看 JVM 已加载的类信息
sm 查看已加载类的方法信息
jad 反编译指定已加载类的源码
classloader 查看 classloader 的继承树,urls,类加载信息
heapdump 类似 jmap 命令的 heap dump 功能
3.2.1 全局监控
使用 dashboard 命令可以概览程序的 线程、内存、GC、运行环境信息。



3.2.2 CPU 高
使用 thread查看所有线程信息,同时会列出每个线程的 CPU 使用率,可以看到图里 ID 为12 的线程 CPU 使用100%。


使用命令 thread 12 查看 CPU 消耗较高的 12 号线程信息,可以看到 CPU 使用较高的方法和行数

上面是先通过观察总体的线程信息,然后查看具体的线程运行情况。如果只是为了寻找 CPU 使用较高的线程,可以直接使用命令 thread -n [显示的线程个数] ,就可以排列出 CPU 使用率 Top N 的线程。


3.2.3 线程池线程状态
使用 thread | grep pool 命令查看线程池里线程信息。



3.2.4 线程死锁检测
使用 thread -b 命令查看直接定位到死锁信息。



3.2.5 反编译
如果怀疑不是自己的代码,可以使用 jad 命令直接反编译 class。


jad 命令还提供了一些其他参数:

# 反编译只显示源码
jad --source-only com.Arthas
# 反编译某个类的某个方法
jad --source-only com.Arthas mysql

3.2.6 查看字段信息
使用 **sc -d -f ** 命令查看类的字段信息。

[arthas@20252]$ sc -d -f com.Arthas
sc -d -f com.Arthas
 class-info        com.Arthas
 code-source       /C:/Users/Niu/Desktop/arthas/target/classes/
 name              com.Arthas
 isInterface       false
 isAnnotation      false
 isEnum            false
 isAnonymousClass  false
 isArray           false
 isLocalClass      false
 isMemberClass     false
 isPrimitive       false
 isSynthetic       false
 simple-name       Arthas
 modifier          public
 annotation
 interfaces
 super-class       +-java.lang.Object
 class-loader      +-sun.misc.Launcher$AppClassLoader@18b4aac2
                     +-sun.misc.Launcher$ExtClassLoader@2ef1e4fa
 classLoaderHash   18b4aac2
 fields            modifierfinal,private,static
                   type    org.slf4j.Logger
                   name    log
                   value   Logger[com.Arthas]

                   modifierprivate,static
                   type    java.util.HashSet
                   name    hashSet
                   value   [count1, count2]

                   modifierprivate,static
                   type    java.util.concurrent.ExecutorService
                   name    executorService
                   value   java.util.concurrent.ThreadPoolExecutor@71c03156[Ru
                           nning, pool size = 1, active threads = 1, queued ta
                           sks = 0, completed tasks = 0]


Affect(row-cnt:1) cost in 9 ms.


3.2.7 查看方法信息
使用 sm 命令查看类的方法信息。

[arthas@22180]$ sm com.Arthas
com.Arthas <init>()V
com.Arthas start()V
com.Arthas thread()V
com.Arthas deadThread()V
com.Arthas lambda$cpuHigh$1()V
com.Arthas cpuHigh()V
com.Arthas lambda$thread$3()V
com.Arthas addHashSetThread()V
com.Arthas cpuNormal()V
com.Arthas cpu()V
com.Arthas lambda$addHashSetThread$0()V
com.Arthas lambda$deadThread$4(Ljava/lang/Object;Ljava/lang/Object;)V
com.Arthas lambda$deadThread$5(Ljava/lang/Object;Ljava/lang/Object;)V
com.Arthas lambda$cpuNormal$2()V
Affect(row-cnt:16) cost in 6 ms.


3.2.8 查看变量的值
使用 ognl 命令,ognl 表达式可以轻松操作想要的信息。

查看静态变量 hashSet 信息。

[arthas@19856]$ ognl '@com.Arthas@hashSet'
@HashSet[
    @String[count1],
    @String[count2],
    @String[count29],
    @String[count28],
    @String[count0],
    @String[count27],
    @String[count5],
    @String[count26],
    @String[count6],
    @String[count25],
    @String[count3],
    @String[count24],

ognl 可以做很多事情 看集合大小,动态添加值,可以参考 ognl 表达式特殊用法( https://github.com/alibaba/arthas/issues/71 )。

3.2.9 trace 命令可以跟踪统计方法耗耗时
访问接口 /getUser ,可以看到耗时信息,看到 com.UserServiceImpl:get()方法耗时较高。


3.2.10 统计方法耗时
使用 monitor 命令监控统计方法的执行情况。

每5秒统计一次 com.UserServiceImpl 类的 get 方法执行情况。monitor -c 5 com.UserServiceImpl get


3.2.11 想观察方法信息
使用 watch 命令轻松查看输入输出参数以及异常等信息

 USAGE:
   watch [-b] [-e] [-x <value>] [-f] [-h] [-n <value>] [-E] [-M <value>] [-s] class-pattern method-pattern express [condition-express]

 SUMMARY:
   Display the input/output parameter, return object, and thrown exception of specified method invocation
   The express may be one of the following expression (evaluated dynamically):
           target : the object
            clazz : the object's class
           method : the constructor or method
           params : the parameters array of method
     params[0..n] : the element of parameters array
        returnObj : the returned object of method
         throwExp : the throw exception of method
         isReturn : the method ended by return
          isThrow : the method ended by throwing exception
            #cost : the execution time in ms of method invocation
 Examples:
   watch -b org.apache.commons.lang.StringUtils isBlank params
   watch -f org.apache.commons.lang.StringUtils isBlank returnObj
   watch org.apache.commons.lang.StringUtils isBlank '{params, target, returnObj}' -x 2
   watch -bf *StringUtils isBlank params
   watch *StringUtils isBlank params[0]
   watch *StringUtils isBlank params[0] params[0].length==1
   watch *StringUtils isBlank params '#cost>100'
   watch -E -b org\.apache\.commons\.lang\.StringUtils isBlank params[0]

 WIKI:
   https://alibaba.github.io/arthas/watch


常用操作:

3.2.12 观察方法的调用路径
使用 stack命令查看方法的调用信息。
stack com.UserServiceImpl mysql


3.2.13 方法调用时空隧道
使用 tt 命令记录方法执行的详细情况。
tt 命令方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测 。

常用操作:
开始记录方法调用信息:tt -t com.UserServiceImpl check

可以看到记录中 INDEX=1001 的记录的 IS-EXP = true ,说明这次调用出现异常。

查看记录的方法调用信息: tt -l

查看调用记录的详细信息(-i 指定 INDEX): tt -i 1001

可以看到 INDEX=1001 的记录的异常信息。

重新发起调用,使用指定记录,使用 -p 重新调用。

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

回复列表

相关推荐