JVM监控及诊断工具之命令行篇

news2024/11/19 1:36:03

文章目录

      • 1. 概述
      • 2. jps:查看正在运行的Java进程
      • 3. jstat:查看JVM统计信息
      • 4. jinfo:实时查看和修改JVM配置参数
      • 5. jmap:导出内存映像文件&内存使用情况
      • 6、jhat:JDK自带堆分析工具
      • 7 jstack:打印JVM中线程快照
      • 8 jcmd:多功能命令行

1. 概述

在这里插入图片描述
性能诊断是软件工程师在日常工作中需要经常面对和解决的问题,在用户体验至上的今天,解决好应用的性能问题能带来非常大的收益。
Java 作为最流行的编程语言之一,其应用性能诊断一直受到业界广泛关注。可能造成Javd应用出现性能问题的因素非常多,例如线程控制、磁盘读写、数据库访问、网络I/O、垃圾收集等。想要定位这些问题,一款优秀的性能诊断工具必不可少。

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

简单命令行工具
在我们刚接触java学习的时候,大家肯定最先了解的两个命令就是javac,java,那么除此之外,还有没有其他的命令可以供我们使用呢?我们进入到安装jdk的bin目录,发现还有一系列辅助工具。这些辅助工具用来获取目标JVM不同方面、不同层次的信息,帮助开发人员很好地解决Java应用程序的一些疑难杂症。

2. jps:查看正在运行的Java进程

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

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

它的基本使用语法为:jps [options] [hostid]

我们还可以通过追加参数,来打印额外的信息。
可以通过jps -help来查看对应的参数信息
在这里插入图片描述
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进程。

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

3. jstat:查看JVM统计信息

在这里插入图片描述
基本情况
jstat(JVM Statistics Monitoring Tool):用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。

在没有GUI图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。常用于检测垃圾回收问题以及内存泄漏问题。

官方文档:

基本语法
它的基本使用语法为:

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

其中vmid是进程id号,也就是jps之后看到的前面的数字
查看命令相关参数:jstat -h或 jstat -help
option参数
选项option可以由以下值构成。
类装载相关的:
-class:显示ClassLoader的相关信息:类的装载、卸载数量、总空间、类装载所消耗的时间等
在这里插入图片描述
interval、count,默认interval在前面,如果只有一个,则默认是interval
在这里插入图片描述
-t(显示Timestamp) -h(每个多少行打印表头)
在这里插入图片描述经验:
我们可以比较Java进程的启动时间以及总 GC时间(GCT列),或者两次测量的间隔时间以及总GC时间的增量,来得出GC时间占运行时间的比例。
如果该比例超过20%,则说明目前堆的压力较大;如果该比例超过90%,则说明堆里几乎没有可用空间,随时都可能抛出 OOM异常。

垃圾回收相关的:
-gc:显示与GC相关的堆信息。包括Eden区、两个Survivor区、老年代、永久代等的容量、已用空间、GC时间合计等信息。
-gccapacity:显示内容与-gc基本相同,但输出主要关注Java堆各个区域使用到的最大、最小空间。
-gcutil:显示内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比。
-gccause:与-gcutil功能一样,但是会额外输出导致最后一次或当前正在发生的Gc产生的原因。
-gcnew:显示新生代GC状况
-gcnewcapacity:显示内容与-gcnew基本相同,输出主要关注使用到的最大、最小空间
-geold:显示老年代GC状况
-gcoldcapacity:显示内容与-gcold基本相同,输出主要关注使用到的最大、最小空间
-gcpermcapacity:显示永久代使用到的最大、最小空间。
JIT相关的:
-compiler:显示JIT编译器编译过的方法、耗时等信息
-printcompilation:输出已经被JIT编译的方法

在这里插入图片描述-gc参数说明
在这里插入图片描述C:总容量,U:已使用量
S0C、S1C:S0区、S1区总容量
S0U、S1U:S0区、S1U已使用量
EC:Eden区总容量
OC:老年代总容量
MC:元空间总容量
CCSC: 压缩类空间总量
YGC、YGCT : YoungGC的次数与时间
FGC、FGCT : FulIGC的次数与时间
GCT :总的GC时间

补充
jstat还可以用来判断是否出现内存泄漏。
第1步:在长时间运行的 Java程序中,我们可以运行jstat命令连续获取多行性能数据,并取这几行数据中 OU列(即已占用的老年代内存)的最小值。
第2步:然后,我们每隔一段较长的时间重复一次上述操作,来获得多组OU最小值。如果这些值呈上涨趋势,则说明该Java程序的老年代内存已使用量在不断上涨,这意味着无法回收的对象在不断增加,因此很有可能存在内存泄漏。

4. jinfo:实时查看和修改JVM配置参数

在这里插入图片描述
基本情况
jinfo(Configuration Info for Java)
查看虚拟机配置参数信息,也可用于调整虚拟机的配置参数。
在很多情况下,Java应用程序不会指定所有的Java虚拟机参数。而此时,开发人员可能不知道某一个具体的Java虚拟机参数的默认值。在这种情况下,可能需要通过查找文档获取某个参数的默认值。这个查找过程可能是非常艰难的。但有了jinfo工具,开发人员可以很方便地找到ava虚拟机参数的当前值。

官方帮助文档:

基本语法
查看:
jinfo -flags 40076
参数赋值的一部分是我们自己设置的,另外一部分是系统自动优化设置的参数信息
在这里插入图片描述查看参数的配置信息
在这里插入图片描述
修改:
jinfo不仅可以查看运行时某一个Java虚拟机参数的实际取值,甚至可以在运行时修改部分参数,并使之立即生效。
但是,并非所有参数都支持动态修改。参数只有被标记为manageable的flag可以被实时修改。其实,这个修改能力是极其有限的。
在这里插入图片描述
修改参数示例:修改仅对当前进程有效,重启后无效
在这里插入图片描述拓展
java -XX:+PrintFlagsInitial 查看所有JVM参数启动的初始值
值前面添加冒号:的是修改之后的值,没有添加的都是没有发生改变的初始值
在这里插入图片描述java -XX:+PrintFlagsFinal 查看所有JVM参数的最终值

5. jmap:导出内存映像文件&内存使用情况

基本情况
jmap(JVM Memory Map):作用一方面是获取dump文件(堆转储快照文件,二进制文件),它还可以获取目标Java进程的内存相关信息,包括Java堆各区域的使用情况、堆中对象的统计信息、类加载信息等。
开发人员可以在控制台中输入命令“jmap -help”查阅jmap工具的具体使用方式和一些标准选项配置。

官方帮助文档:

基本语法
在这里插入图片描述
它的基本使用语法为:

jmlp [option] <pid>
jmap [option] <executable <core>
jmap [option] [server_id@]<remote server IP or hostname>

在这里插入图片描述
在这里插入图片描述一般来说,使用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-frameinformation about local objects
说明:
1)通常在写Heap Dump文件前会触发一次Full GC,所以heap dump文件里保存的都是FullGC后留下的对象信息。(自动)
2)由于生成dump文件比较耗时,因此大家需要耐心等待,尤其是大N存镜像生成dump文件则需要耗费更长的时间来完成。

使用1:导出内存映像文件

手动方式:

jmap -dump:format=b,file=<filename.hprof>
jmap -dump:live,format=b,file=<filename.hprof>
format=b表示生成的是标准的dump文件,用来进行格式限定
一般使用的是第二种方式,也就是生成堆中存活对象的快照,这种方式生成的dump文件更小,传输处理都更方便。

由于jmap将访问堆中的所有对象,为了保证在此过程中不被应用线程干扰,jmap需要借助安全点机制,让所有线程停留在不改变堆中数据的状态。也就是说,由jmap导出的堆快照必定是安全点位置的。这可能导致基于该堆快照的分析结果存在偏差。
举个例子,假设在编译生成的机器码中,某些对象的生命周期在两个安全点之间,那么:live选项将无法探知到这些对象。
另外,如果某个线程长时间无法跑到安全点,jmap将一直等下去。与前面讲的jstat则不同,垃圾回收器会主动将jstat所需要的摘要数据保存至固定位置之中,而jstat只需直接读取即可。

在这里插入图片描述在这里插入图片描述

自动方式:

当程序发生OOM退出系统时,一些瞬时信息都随着程序的终止而消失,而重现OOM问题往往比较困难或者耗时。此时若能在OOM时,自动导出dump文件就显得非常迫切。
这里介绍一种比较常用的取得堆快照文件的方法,即使用:
-XX:+HeapDumpOnOutOfMemoryError:在程序发生OOM时,导出应用程序的当前堆快照。-XX:HeapDumpPath:可以指定堆快照的保存位置。
比如:-Xmx100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\5.hprof

自动的方式是只有在发生OOM之前才会生成dump文件,手动的方式是随时可以生成dump文件。
在这里插入图片描述在这里插入图片描述使用2:显示堆内存相关信息
jmap -heap 进程id
jmap -histo 进程id
jmap -heap 进程id只是时间点上的堆信息,而jstat后面可以添加参数,可以指定时间动态观察数据改变情况,而图形化界面工具,例如jvisualvm等,它们可以用图表的方式动态展示出相关信息,更加直观明了
jmap -histo 进程id 输出堆中对象的同级信息,包括类、实例数量和合计容量,也是这一时刻的内存中的对象信息

6、jhat:JDK自带堆分析工具

基本情况
jhat(JVM Heap Analysis Tool):
Sun JDK提供的jhat命令有jmap命令搭配使用,用于分析jmap生成的heap dump文件(堆转储快照)。jhat内置了一个微型的HTTP/HTML服务器,生成dump文件的分析结果后,用户可以在浏览器中查看分析结果(分析虚拟机转储快照信息)。
使用了jhat命令,就启动了一个http服务,端口是7000,即http://localhost:7000/,就可以在浏览器里分析。

说明:jhat命令在DK9、JDK10中已经被删除,官方建议用VisualVM代替。因为后续被废弃,所以只是了解一下。

基本语法
它的基本使用语法为:

jhat [option] [ dumpfile]

在这里插入图片描述在这里插入图片描述

7 jstack:打印JVM中线程快照

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

官方帮助文档:

在thread dump中,要留意下面几种状态
死锁,Deadlock(重点关注)
等待资源,waiting on condition(重点关注)
等待获取监视器,Waiting on monitor entry(重点关注)
阻塞,Blocked(重点关注)
执行中,Runnable
暂停,Suspended
对象等待中,0bject.wait()或TIMED_WAITING
停止,Parked
在这里插入图片描述排查程序长时间停顿,查看个线程的转态,排查重点状态。

public class ThreadDeadLock {

    public static void main(String[] args) {

        StringBuilder s1 = new StringBuilder();
        StringBuilder s2 = new StringBuilder();

        new Thread() {
            @Override
            public void run() {

                synchronized (s1) {

                    s1.append("a");
                    s2.append("1");

                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    synchronized (s2) {
                        s1.append("b");
                        s2.append("2");

                        System.out.println(s1);
                        System.out.println(s2);
                    }
                }
            }
        }.start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (s2) {

                    s1.append("c");
                    s2.append("3");

                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    synchronized (s1) {
                        s1.append("d");
                        s2.append("4");

                        System.out.println(s1);
                        System.out.println(s2);
                    }
                }
            }
        }).start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                Map<Thread, StackTraceElement[]> all = Thread.getAllStackTraces();//追踪当前进程中的所有的线程
                Set<Map.Entry<Thread, StackTraceElement[]>> entries = all.entrySet();
                for (Map.Entry<Thread, StackTraceElement[]> en : entries) {
                    Thread t = en.getKey();
                    StackTraceElement[] v = en.getValue();
                    System.out.println("【Thread name is :" + t.getName() + "】");
                    for (StackTraceElement s : v) {
                        System.out.println("\t" + s.toString());
                    }
                }
            }
        }).start();
    }
}

在这里插入图片描述
在这里插入图片描述

2022-12-10 13:31:22
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.131-b11 mixed mode):

"DestroyJavaVM" #23 prio=5 os_prio=0 tid=0x000000000311e800 nid=0x2d78 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Thread-1" #21 prio=5 os_prio=0 tid=0x00000000214e1000 nid=0x2370 waiting for monitor entry [0x0000000021e8e000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at com.atguigu.springcloud.jvm.ThreadDeadLock$2.run(ThreadDeadLock.java:63)
	- waiting to lock <0x000000076e2b7970> (a java.lang.StringBuilder)
	- locked <0x000000076e2b79b8> (a java.lang.StringBuilder)
	at java.lang.Thread.run(Thread.java:748)

"Thread-0" #20 prio=5 os_prio=0 tid=0x00000000214ea000 nid=0x293c waiting for monitor entry [0x0000000021d8f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at com.atguigu.springcloud.jvm.ThreadDeadLock$1.run(ThreadDeadLock.java:35)
	- waiting to lock <0x000000076e2b79b8> (a java.lang.StringBuilder)
	- locked <0x000000076e2b7970> (a java.lang.StringBuilder)

"Service Thread" #19 daemon prio=9 os_prio=0 tid=0x000000001eb91000 nid=0x1074 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread11" #18 daemon prio=9 os_prio=2 tid=0x000000001eb0a800 nid=0x3fc waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread10" #17 daemon prio=9 os_prio=2 tid=0x000000001eb0d800 nid=0x2628 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread9" #16 daemon prio=9 os_prio=2 tid=0x000000001eb0b800 nid=0x3114 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread8" #15 daemon prio=9 os_prio=2 tid=0x000000001eb11800 nid=0x290c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread7" #14 daemon prio=9 os_prio=2 tid=0x000000001eafa000 nid=0xe0c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread6" #13 daemon prio=9 os_prio=2 tid=0x000000001eaea800 nid=0x2aa4 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread5" #12 daemon prio=9 os_prio=2 tid=0x000000001eac5000 nid=0x768 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread4" #11 daemon prio=9 os_prio=2 tid=0x000000001eab4000 nid=0x2078 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread3" #10 daemon prio=9 os_prio=2 tid=0x000000001ea9f800 nid=0x311c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x000000001ea96800 nid=0x3ac waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x000000001ea93000 nid=0x2650 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x000000001ea8f000 nid=0x1fb8 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x000000001ea72000 nid=0x2174 runnable [0x000000002058e000]
   java.lang.Thread.State: RUNNABLE
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
	at java.net.SocketInputStream.read(SocketInputStream.java:171)
	at java.net.SocketInputStream.read(SocketInputStream.java:141)
	at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
	at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
	at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
	- locked <0x000000076e3c7090> (a java.io.InputStreamReader)
	at java.io.InputStreamReader.read(InputStreamReader.java:184)
	at java.io.BufferedReader.fill(BufferedReader.java:161)
	at java.io.BufferedReader.readLine(BufferedReader.java:324)
	- locked <0x000000076e3c7090> (a java.io.InputStreamReader)
	at java.io.BufferedReader.readLine(BufferedReader.java:389)
	at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x000000001e99f000 nid=0x303c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000001e946000 nid=0x3490 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x000000001e926800 nid=0x1e18 in Object.wait() [0x000000002028f000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x000000076e108ec8> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
	- locked <0x000000076e108ec8> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
	at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x000000001cecd000 nid=0xdac in Object.wait() [0x000000002018e000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x000000076e106b68> (a java.lang.ref.Reference$Lock)
	at java.lang.Object.wait(Object.java:502)
	at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
	- locked <0x000000076e106b68> (a java.lang.ref.Reference$Lock)
	at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"VM Thread" os_prio=2 tid=0x000000001e904800 nid=0x20fc runnable 

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00000000033c8800 nid=0x15c8 runnable 

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00000000033ca000 nid=0x29d8 runnable 

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00000000033cb800 nid=0x2388 runnable 

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00000000033cd000 nid=0x306c runnable 

"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00000000033d0800 nid=0x1304 runnable 

"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00000000033d1800 nid=0x1b68 runnable 

"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x00000000033d4800 nid=0x3714 runnable 

"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00000000033d6000 nid=0x226c runnable 

"GC task thread#8 (ParallelGC)" os_prio=0 tid=0x00000000033d7000 nid=0x34bc runnable 

"GC task thread#9 (ParallelGC)" os_prio=0 tid=0x00000000033d8000 nid=0x216c runnable 

"GC task thread#10 (ParallelGC)" os_prio=0 tid=0x00000000033d9800 nid=0x1008 runnable 

"GC task thread#11 (ParallelGC)" os_prio=0 tid=0x00000000033dc800 nid=0x2db0 runnable 

"GC task thread#12 (ParallelGC)" os_prio=0 tid=0x00000000033dd800 nid=0xa00 runnable 

"VM Periodic Task Thread" os_prio=2 tid=0x000000001ebc6000 nid=0x2654 waiting on condition 

JNI global references: 33


Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x00000000214e4638 (object 0x000000076e2b7970, a java.lang.StringBuilder),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x000000001ced5338 (object 0x000000076e2b79b8, a java.lang.StringBuilder),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
	at com.atguigu.springcloud.jvm.ThreadDeadLock$2.run(ThreadDeadLock.java:63)
	- waiting to lock <0x000000076e2b7970> (a java.lang.StringBuilder)
	- locked <0x000000076e2b79b8> (a java.lang.StringBuilder)
	at java.lang.Thread.run(Thread.java:748)
"Thread-0":
	at com.atguigu.springcloud.jvm.ThreadDeadLock$1.run(ThreadDeadLock.java:35)
	- waiting to lock <0x000000076e2b79b8> (a java.lang.StringBuilder)
	- locked <0x000000076e2b7970> (a java.lang.StringBuilder)

Found 1 deadlock.

8 jcmd:多功能命令行

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

官方帮助文档:

jcmd拥有jmap的大部分功能,并且在oracle的官方网站上也推荐使用jcmd命令代jmap命令
在这里插入图片描述
在这里插入图片描述jcmd -l 列出所有的JVM进程
jcmd 进程号 help 针对指定的进程,列出支持的所有具体命令
jcmd 进程号 具体命令 显示指定进程的指令命令的数据

根据以上命令来替换之前的那些操作:
Thread.print 可以替换 jstack指令
GC.class_histogram 可以替换 jmap中的-histo操作
GC.heap_dump 可以替换 jmap中的-dump操作
GC.run 可以查看GC的执行情况
VM.uptime 可以查看程序的总执行时间,可以替换jstat指令中的-t操作
VM.system_properties 可以替换 jinfo -sysprops 进程id
VM.flags 可以获取JVM的配置参数信息,可以替换jinfo -flags 进程id

在这里插入图片描述
注:本文是学习 尚硅谷宋红康JVM全套教程(详解java虚拟机)所做笔记。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/82331.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于微信小程序的旅游系统-计算机毕业设计

项目介绍 随着人民生活水平的提高,旅游业已经越来越大众化,而旅游业的核心是信息,不论是对旅游管理部门、对旅游企业,或是对旅游者而言,有效的获取旅游信息,都显得特别重要.自助定制游将使旅游相关信息管理工作规范化、信息化、程序化,提供旅游景点、旅游线路,旅游新闻等服务本…

_5LeetCode代码随想录算法训练营第五天-C++哈希表

_5LeetCode代码随想录算法训练营第五天-C哈希表 LeetCode 242.有效的字母异位词LeetCode 349.两个数组的交集LeetCode 202.快乐数LeetCode 1.两数之和 本文截图参考代码随想录&#xff1a;https://programmercarl.com/ 哈希表 定义 哈希表是根据键值而直接进行访问的数据结…

shell 创建子进程及并行延时执行命令方法

shell 创建子进程方法 1. 什么是shell子进程 子进程&#xff0c;是从父子进程的概念出发的&#xff0c;unix操作系统的进程从init进程开始&#xff08;init进程为1,而进程号0为系统原始进程&#xff0c;以下讨论的进程原则上不包括进程0)均有其对应的子进程&#xff0c;就算是…

POI通过模板导出excel(包含表头合并处理)

最近接触到比较多poi相关的需求&#xff0c;总结一下通过模板导出以及表头合并的一些复杂情况处理。 简单使用的话可以参考下我之前写的 POI实现导入导出excel 目录&#xff1a;1、POI通过模板导出2、POI表头合并处理1、POI通过模板导出 其实通过模板导出的原理&#xff0c;无…

2021 年年度最佳开源软件

Svelte https://svelte.dev/ Svelte 是一种全新的构建用户界面的方法。传统框架如 React 和 Vue 在浏览器中需要做大量的工作&#xff0c;而 Svelte 将这些工作放到构建应用程序的编译阶段来处理。 与使用虚拟&#xff08;virtual&#xff09;DOM 差异对比不同。Svelte 编写的…

DAla-Gly-Gly,77286-90-9

Substrate for bacterial D-aminopeptidases.细菌d -氨基肽酶的底物。 编号: 191616中文名称: 三肽DAla-Gly-Gly英文名: DAla-Gly-GlyCAS号: 77286-90-9单字母: H2N-DAla-GG-OH三字母: H2N-DAla-Gly-Gly-COOH氨基酸个数: 3分子式: C7H13N3O4平均分子量: 203.2精确分子量: 203.0…

虚拟现实 VR 碰撞 3D 可视化,图扑打造一体化管控平台

工信部《虚拟现实产业发展白皮书 5.0 》中明确提出&#xff1a;“通过财政资金促进虚拟现实技术产业化&#xff0c;支持面向工业、文化、教育等重点行业的虚拟现实技术应用”。 虚拟现实 VR 技术以用户体验视角为中心&#xff0c;跟踪反馈在 3D 场景中的动作&#xff0c;借助软…

kali工具学习

目录 1.waybackurls 网络爬虫&#xff0c;url搜索 2.wafw00f 检测网站用了什么waf 3.theHarvester ip、邮箱、host搜集 4. oneforall 子域名搜集 5. nmap kali自带的扫描工具 6. whatweb 指纹查询 1.waybackurls 网络爬虫&#xff0c;url搜索 2.wafw00f 检测网…

阿里巴巴注册中心nacos

目录 一、配置中心介绍 1、Spring Cloud Config 2、Nacos替换Config &#xff08;1&#xff09;应用场景 二、读取Nacos配置中心的配置文件 1、在Nacos创建统一配置文件 2、以service-statistics模块为例 3、补充&#xff1a;springboot配置文件加载顺序 三、名称空间…

网络实验之VRRP协议

一、VRRP协议简介 虚拟路由冗余协议(Virtual Router Redundancy Protocol&#xff0c;简称VRRP)是由IETF提出的解决局域网中配置静态网关出现单点失效现象的路由协议。VRRP是一种路由容错协议&#xff0c;也可以叫做备份路由协议。一个局域网络内的所有主机都设置缺省路由&…

MySQL入门阶段这一篇就够了-学习笔记(手敲1.5万字)

前言 虽然在大一下学期&#xff0c;就已经接触到了MySQL&#xff0c;但是那个时候只是会用MySQL进行增删改查&#xff0c;在大三上学期&#xff0c;尝试投简历寻找实习时&#xff0c;对方公司对于程序员的MySQL水平有很高的要求&#xff0c;所以我开始系统化的学习MySQL。顺便…

想写出复用性强的组件?快来试试 Storybook 吧

简介 Storybook 是 UI 组件的开发环境&#xff0c;它允许开发者浏览组件库&#xff0c;查看每个组件的不同状态&#xff0c;以及交互地开发和测试组件。 Storybook 可帮助你记录组件以供重用&#xff0c;并自动对组件进行可视化测试以防止出现错误。 开始 在对 Storybook 有…

halcon measure_pos和measure_pairs详解

这两个算子作为halcon一维测量的关键&#xff0c;看了这两个算子的多个博客&#xff0c;也没搞清楚里面几个参数的意义和测量的原理&#xff0c;决定自己详细试一下&#xff0c;将测试的过程详细记录下来&#xff0c;供以后需要参考的朋友使用&#xff0c;本文将从以下几个点说…

使用bat脚本运行python脚本,bat出现闪退,怎么解决?

前言 本文是该专栏的第4篇,后面会持续分享python的各种干货知识,值得关注。 工作上为了方便,很多时候我们会设置一个bat脚本来双击运行python脚本,这样既方便又能在工作上节约大量时间。 但是,你或许会碰到这样的情况,当双击bat脚本的时候,bat窗口界面会直接出现闪退关…

DM8设置自动备份,达梦数据库,自动备份。详细步骤。常用命令,启动关闭数据库,查看DMAP状态

常用命令 DmServiceDAMENG.service改成自己bin目录下文件名 运维常见问题&#xff0c;官方文档 注意事项 登录客户端工具&#xff0c;一定要使用SYSDBA用户进行下面的客户端操作 登录数据库主机&#xff0c;一定要使用安装数据库时创建的dmdba用户 定时备份前请先配置本地…

引入新模块都在用这个注解,它是如何生效的?|原创

本文讲解了Enable 类注解是如何生效的以及其核心注解 Import 的原理&#xff0c;并且用 EnableAsync 注解来举例。点击上方“后端开发技术”&#xff0c;选择“设为星标” &#xff0c;优质资源及时送达在项目开发的过程中&#xff0c;我们会遇到很多名字为 Enablexxx 的注解&a…

OA系统解决方案

一、OA系统解决方案介绍 OA系统&#xff0c;即办公自动化系统&#xff08;Office Assistant简称OA&#xff09;&#xff0c;它是一个集成了企业信息发布、公文与信息管理、公文处理、知识管理、内部通讯、协同办公等办公与管理应用功能一体的协同 办公系统。OA系统解决方案则是…

Linux——详解共享内存shared memory

目录 一.共享内存介绍 &#xff08;一&#xff09;.什么是共享内存 &#xff08;二&#xff09;.共享内存优点 &#xff08;三&#xff09;.共享内存缺点 二.共享内存使用 &#xff08;一&#xff09;.创建—shmget ①key ②size ③shmflg ④返回值 &#xff08;二&…

CRMEB电商商城系统腾讯云ECS服务器安装配置搭建教程文档

一、推荐使用宝塔Linux面板&#xff0c;简单好用。二、放行服务器端口。详细步骤&#xff1a; 1.登录腾讯云服务器&#xff0c;点击右上角“控制台” 2.我的资源&#xff0c;点击进入云服务器 3.进入实例列表&#xff0c;选择您要安装的服务器&#xff0c;点击更多 4.选择重装…

Hadoop 如何保证自己的江湖地位?Yarn 功不可没

前言 任何计算任务的运行都离不开计算资源&#xff0c;比如 CPU、内存等&#xff0c;那么如何对于计算资源的管理调度就成为了一个重点。大数据领域中的 Hadoop 之所以一家独大&#xff0c;深受市场的欢迎&#xff0c;和他们设计了一个通用的资源管理调度平台 Yarn 密不可分&a…