深入理解Java虚拟机系列 --13 性能监控与调优篇 --01JVM命令行监控工具

  

因为热爱所以坚持,因为热爱所以等待。熬过漫长无戏可演的日子,终于换来了人生的春天,共勉!!!

目录

性能指标

JVM命令行监控工具

①概述

② jps(Java Process Status):查看正在运行的Java进程

③ jstat(JVM Statistics Monitoring Tool):查看JVM统计信息

④ jinfo 实时查看和修改JVM配置参数

⑤jmap(JVM Memory Map):内存使用情况

⑥jhat(自带堆分析工具)

扫描二维码关注公众号,回复: 14140506 查看本文章

⑦jstack(打印JVM中线程快照)

⑧jcmd(多功能命令行)

⑨jstatd(远程主机信息收集)


性能指标

①.停顿时间(或响应时间)

②.吞吐量(单位时间内完成的工作量请求的量度 || 运行代码时间 / (运行代码时间 + 内存回收时间)

③.并发数(同一时刻,对服务器有实际交互的请求数)

④.内存占用(java堆所占内存大小)

JVM命令行监控工具

①概述

性能诊断是软件工程师在日常工作中需要经常面对和解决的问题,在用户体验至上的今天,解决好应用的性能问题能带来非常大的收益。

Java作为最流行的编程语言之一,其应用性能诊断一直受到业界广泛 关注。可能造成Java应用出现性能问题的因素非常多,例如线程控制、磁盘读写、数据库访问、网络I/0、垃圾收集等。想要定位这些问题,一款优秀的性能诊断工具必不可少。

  • 使用数据说明问题,使用知识分析问题,使用工具处理问题。
  • 无监控、不调优!

② jps(Java Process Status):查看正在运行的Java进程

显示指定系统内所有的HotSpot虚拟机进程(查看虚拟机进程信息),可用于查询正在
运行的虚拟机进程。

说明:对于本地虚拟机进程来说,进程的本地虚拟机ID与操作系统的进程ID是一-致
的,是唯一的

 

基本语法:jps [ options ] [ hostid ]

1、【options参数】

  • -q: 仅仅显示LVMID (local virtual machine id), 即本地虚拟机唯一 id,不显示主类的名称
  • -l: 输出应用程序主类的全类名或如果进程执行的是jar包则输出jar完整路径
  • -m: 输出虚拟机进程启动时传递给主类main()的参数
  • -v: 列出虚拟机进程启动时的JVM参数。比如:( -Xms20m -Xmx50m)是 启动程序指定的jvm参数。

说明: 以上参数可以综合使用。
补充: 如果某Java进程关闭了默认开启的UsePerfData参数(即参数-XX:-UsePerfData),那么jps命令(以及下面介绍的jstat)将无法探知该Java进程。
 

2、【hostid参数】

RMI注册表中注册的主机名。

  • 如果想要远程监控主机上的java程序,需要安装jstatd.

  • 对于具有更严格的安全实践的网络场所而言,可能使用一个自定义的策略文件来显示对特定的可信主机或网络的访问,尽管这种技术容易受到IP地址欺诈攻击
  • 如果安全问题无法使用一个定制的策略文件来处理,那么最安全的操作是不运行jstatd服务器,而是在本地使用jstat和jps工具。

③ jstat(JVM Statistics Monitoring Tool):查看JVM统计信息

  • jstat(JVM Statistics Monitoring Tool): 用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。
  • 在没有GUI图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。常用于检测垃圾回收问题以及内存泄漏问题。

基本语法:jstat [ option ] [ -t ] [ -h<lines> ]  <vmid>(进程号) [ interval ] [ count ]

1、【option参数】

  • 类装载相关的:

        -class: 显示ClassLoader的相关信息:类的裴载、卸载数量、总空间、
类装载所消耗的时间等

  • 垃圾回收相关的:(重要)

        -gc: 显示与GC相关的堆信息。包括Eden区、两个Survivor区、老年代、
永久代等的容量、已用空间、GC时间合计等信息。

数据含义:

1️⃣新生代相关:

S0C: 幸存者0区总容量(单位字节)      S1C: 幸存者1区总容量    S0U: 幸存者0区已经使用的容量    S1U: 幸存者1区使用的容量    EC: Eden空间的总容量    EU: Eden空间的已使用容量

2️⃣老年代相关:

OC: 老年代总容量(字节)   OU: 老年代已使用容量   

3️⃣方法区(元空间)相关:

MC: 方法区的大小   MU: 方法区已使用   CCSC: 压缩类的总容量    CCSU: 压缩类的使用的容量

4️⃣其他:

YGC: young GC 发生的次数   YGCT: young GC消耗的时间    FGC:  Full GC的次数   FGCT: Full GC发生的时间   GCT: 总共GC发生的时间


        -gccapacity: 显示内容与-gc基本相同,但输出主要关注Java堆各个区域使用到的最大、最小空间。 

        -gcutil: 显示内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比。        

 

         -gccause:-gcutil功能 一样, 但是会额外输出导致最后一次或当前正在发生的GC产生的原因。                    
        -gcnew: 显示新生代GC状况

        -gcnewcapacity: 显示内容与-gcnew基本相同,输出主要关注使用到的
最大、最小空间

        -geold: 显示老年代GC状况

  • JIT相关的:

        -compiler: 显示JIT编译器编译过的方法、耗时等信息
        -printcompilation:输出已经被JIT编译的方法

        示例:

        

         

2、【interval参数】用于指定输出统计数据的范围,单位为毫秒,即查询间隔

3、【count参数】用于指定查询的总次数

示例:写一个默认是interval 两个是interval和count

 4、【- t 参数】可以在输出信息前加上一个Timestamp列,显示程序的运行时

        我们可以比较Java 进程的启动时间以及总GC时间(GCT列),或者两次测量的间隔时间
以及总GC时间的增量,来得出GC时间占运行时间的比例。
        如果该比例超过20%, 则说明目前堆的压力较大;如果该比例超过90%, 则说明堆里几乎没有
可用空间,随时都可能抛出00M异常。

5、【- h <lines> 参数】可以在周期性数据输出时,输出lines行后输出一个表头信息

示例:

④ jinfo 实时查看和修改JVM配置参数

  • jinfo不仅可以查看运行时某一个Java虚拟机参数的实际取值,甚至可以在运行时修改部分参数,并使之立即生效。
  • 但是,并非所有参数都支持动态修改。参数只有被标记为manageable的flag可以被实时修改其实,这个修改能力是极其有限的。

查看:

  • jinfo -sysprops PID 可以查看System.getProperties() 获得的参数
  • jinfo -flags PID 查看曾经赋值过的一些参数
  • jinfo -flag 具体参数 PID 查看某个java进程的具体参数的值

修改:

  • jinfo -flag [+]- 具体参数 PID  针对boolean类型进行更改
  • jinfo -flag 具体参数=具体参数值 PID  针对非boolean类型 

         

 扩展:

  • java -XX: +PrintFlagslnitial  查看所有JVM参数启动的初始值
  • java -XX:+PrintFlagsFinal  查看所有JVM参数的最终值
  • java -XX:+ PrintCommandLineFlags  查看那些已经被用户或者JVM设置过的详细的XX参数的名称和值

⑤jmap(JVM Memory Map):内存使用情况

作用:

  • 一方面是 获取dump文件(堆转储快照文件,二进制文件),
  • 另一方面还可以获取目标Java进程的内存相关信息,包括Java堆各区域的使用情况堆中对象的统计信息、类加载信息等。

开发人员可以在控制台中输入命令“jmap -help" 查阅jmap工具的具体使用方式和一些标准
选项配置。
 

基本使用语法为:

  • jmap [option] <pid>
  • jmap [option] <executable <core>
  • jmap [option] [server_ id@] <remote server IP or hostname>

【option参数】

① -dump (导出内存映像文件)

一般来说,使用jmap指令生成dump文件的操作算得上是最常用的jmap命令之一,将堆中所有
存活对象导出至一个文件之中。
Heap Dump又叫做堆存储文件,指一个Java进程在某个时间点的内存快照。Heap Dump在触
发内存快照的时候会保存此刻的信息如下:

  • All Objects(所有对象的信息)

        Class, fields, primitive values and references

  • All Classes (所有类相关信息)

        ClassLoader,name,super class,static fields

  • Garbage Collection Roots(垃圾回收根对象)

        Objects defined to be reachable by the JVM

  • Thread Stacks and Local Variables(线程栈和局部变量表)

        The call-stacks of threads at the moment of the snapshot, and per-frame information about local objects


说明:
1.通常在写Heap Dump文件前会触发一次Full GC,所以heap dump文件里保存的都是
Full GC后留下的对象信息。(自动的方式)

2.由于生成dump文件比较耗时,因此大家需要耐心等待,尤其是大内存镜像生成dump文件
则需要耗费更长的时间来完成。

(1)手动的方式:  jmap -dump:format=b,file= < filename.hprof> <pid>
                                jmap -dump:live,format=b,file= <filename.hprof> <pid>

示例:

(2)自动的方式: 

当程序发生OOM退出系统时,一些瞬时信息都随着程序的终止而消失,而重现OOM问题往往比
较困难或者耗时。此时若能在OOM时,自动导出dump文件就显得非常迫切。

  • -XX: +HeapDumpOnOutOfMemoryError(在程序发生OOM时,导出应用程序的当前堆快照)                      
  • -XX:HeapDumpPath=<filename.hprof> (指定堆快照的保存位置)

例如:

  • -Xmx100m -XX : +HeapDumpOnOutOfMemoryError  -XX:HeapDumpPath=D:\3.hprof


② -heap (显示堆内存相关信息)

  • jmap -heap <pid> 显示堆内存信息(时间点)

③ -histo(显示对象信息)

  • jmap -histo <pid> 

④ -permstat (查看ClassLoader信息)

  • jmap -permstat pid 

⑤ -finalizerinfo (查看finalizer队列中的信息)

  • jmap -finalizerinfo pid

⑥小结:

由于jmap将访问堆中的所有对象,为了保证在此过程中不被应用线程干扰,jmap需要借助安
全点机制
,让所有线程停留在不改变堆中数据的状态。也就是说,由jmap 导出的堆快照必定
是安全点位置的。这可能导致基于该堆快照的分析结果存在偏差

  • 假设在编译生成的机器码中,某些对象的生命周期在两个安全点之间,那么:live选项将无法探知到这些对象。
  • 另外,如果某个线程长时间无法跑到安全点,jmap将一直等 下去。与前面讲的jstat则不同,垃圾回收器会主动将jstat所需要的摘要数据保存至固定位置之中,而jstat只需直接读取即可。

⑥jhat(自带堆分析工具)

Sun JDK提供的jhat 命令与jmap命令搭配使用,用于分析jmap生成的heap dump文件(堆转储快照)。jhat内置了一个微型的HTTP/HTML服务器,生成dump文件的分析结果后,用户可以在浏览器中查看分析结果(分析虚拟机转储快照信息)。

使用了jhat命令,就启动了一个http服务,端口是7000,即http://localhost: 7000/,就可以在浏览器里分析。
说明: jhat命 令在JDK9、JDK10中 已经被删除,官方建议用VisualVM代替。
 

参数说明:

⑦jstack(打印JVM中线程快照)

jstack(JVMStackTrace):用于生成虚拟机指定进程当前时刻的线程快照(虚拟机堆栈跟
踪)。线程快照就是当前虚拟机内指定进程的每一条线程正在执行的方法堆栈的集合。
生成线程快照的作用:可用于定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求
外部资源导致的长时间等待等问题。这些都是导致线程长时间停顿的常见原因。当线程出现停
顿时,就可以用jstack显示各个线程调用的堆栈情况。


官方帮助文档:
https:/ /docs. oracle. com/ en/java/javase/11/ tools/jstack. html

在thread dump中,要留意下面几种状态

  • 死锁,Deadlock (重点关注)

  • 等待资源,Waiting on condition (重点关注)

  • 等待获取监视器,Waiting on monitor entry (重点关注)

  • 阻塞,Blocked (重点关注)

  • 执行中,Runnable
  • 暂停,Suspended

参数列表

 ⑧jcmd(多功能命令行)

在JDK 1.7以后, 新增了一个命令行工具jcmd。
它是一个多功能的工具,可以用来实现前面除了jstat之外所有命令的功能。比如:用它来导
出堆、内存使用、查看Java进程、导出线程信息、执行GC、JVM运行时间等。

官方帮助文档:
https:/ /docs . oracle. com/ en/ java/javase/ 11/tools/j cmd. html

jcmd拥有jmap的大部分功能,并且在0racle的官方网站上也推荐使用jcmd命令代jmap命令
 

参数列表 

⑨jstatd(远程主机信息收集)

之前的指令只涉及到监控本机的Java应用程序,而在这些工具中,一些监控工具也支持对远
程计算机的监控(如jps、jstat)。为了启用远程监控,则需要配合使用jstatd工具。

命令jstatd是一个RMI服务端程序,它的作用相当于代理服务器,建立本地计算机与远程监
控工具的通信,jstatd服务器将本机的Java应用程序信息传递到远程计算机。

   

下一篇 14 性能监控与调优篇02

参考视频 : 尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机)
参考书籍 : 深入理解Java虚拟机

猜你喜欢

转载自blog.csdn.net/qq_43295483/article/details/120382134