这篇文章主要来介绍下 JDK 内置的命令,话不多说,让我们开始吧!
javap
使用 javap
可以查看 Java 字节码反编译的源文件,javap
的命令格式如下:
下面来演示下用 javap -c
对代码进行反编译,首先写个 HelloWorld
类,如下:
public class HelloWorld { public static void main(String []args) { System.out.println("Hello World"); } }
接着使用 javap -c HelloWorld.class
就可以反编译得到如下结果:
Compiled from "HelloWorld.java" public class HelloWorld { public HelloWorld(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3 // String Hello World 5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return }
jps
jps
是用来查询当前所有进程 pid 的,命令的用法如下图所示:
执行 jps
可以获取本机 Java 程序的 pid,运行结果如下:
[root@wupx ~]# jps 8825 spring-boot-0.0.1-SNAPSHOT.jar
使用 jps -mlvV
可以获取到这个进程的 pid、jar 包的名字以及 JVM 参数等。
[root@wupx ~]# jps -mlvV 8825 /root/spring-boot-0.0.1-SNAPSHOT.jar --server.port=8090 --logging.file=/root/log/spring-boot.log -Xmx1024m -Xms1024m
jstat
jstat
主要用于监控 JVM,主要是 GC 信息,在性能优化的时候经常用到,命令内容如下所示:
比如,上面我们通过 jps
查到的进程号 8825,我们使用 jstat -gc 8825
来查看该进程的 GC 信息:
[root@wupx ~]# jstat -gc 8825 S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT 65536.0 69120.0 0.0 160.0 10425344.0 1036247.8 21135360.0 19489859.7 84608.0 81123.8 9600.0 8834.1 99517 2070.459 0 0.000 2070.459
其中 S0C
表示当前 Survivor0
的容量,S1C
表示当前 Survivor1
的容量,S0U
表示当前 Survivor0
的利用率,S1U
表示当前 Survivor1
的利用率,EC
表示 Eden 的容量,EU
表示 Eden 的利用率,OC
表示老年代的容量,OU
表示老年代的利用率,MC
表示 Metaspace 的容量,MU
表示 Metaspace 的利用率,CCSC
表示类指针压缩空间容量,CCSU
表示使用的类指针压缩空间,YGC
表示新生代 GC 的次数,YGCT
表示新生代 GC 的时间,FGC
表示 Full Gc 的次数,FGCT
表示 Full GC 的时间,GCT
表示 GC 总时间。
每个对象都有一个指向它自身类的指针,_klass: 指向类的 4 字节指针,64 位平台上 _klass: 指向类的 8 字节的指针,为了节约这些空间,引入了类指针压缩空间。
jcmd
jcmd
可以查看 JVM 信息,常用的命令内容如下:
先使用 jcmd 8825 help
来查看都支持什么命令:
[root@wupx ~]# jcmd 8825 help 8825: The following commands are available: JFR.stop JFR.start JFR.dump JFR.check VM.native_memory VM.check_commercial_features VM.unlock_commercial_features ManagementAgent.stop ManagementAgent.start_local ManagementAgent.start VM.classloader_stats GC.rotate_log Thread.print GC.class_stats GC.class_histogram GC.heap_dump GC.finalizer_info GC.heap_info GC.run_finalization GC.run VM.uptime VM.dynlibs VM.flags VM.system_properties VM.command_line VM.version help
下面我就选一个参数给大家举个例子,比如打印堆的信息,使用 jcmd 8825 GC.heap_dump
命令:
[root@wupx ~]# jcmd 8825 GC.heap_info 8825: PSYoungGen total 628736K, used 41772K [0x0000000715a00000, 0x0000000746480000, 0x00000007c0000000) eden space 609792K, 4% used [0x0000000715a00000,0x00000007173d5478,0x000000073ad80000) from space 18944K, 80% used [0x000000073ad80000,0x000000073bc75e68,0x000000073c000000) to space 19968K, 0% used [0x0000000745100000,0x0000000745100000,0x0000000746480000) ParOldGen total 250880K, used 21756K [0x00000005c0e00000, 0x00000005d0300000, 0x0000000715a00000) object space 250880K, 8% used [0x00000005c0e00000,0x00000005c233f160,0x00000005d0300000) Metaspace used 44797K, capacity 45562K, committed 45824K, reserved 1089536K class space used 5669K, capacity 5832K, committed 5888K, reserved 1048576K
可以看出可以获取新生代、老年代、元空间、Eden、From Survivor 以及 To Survivor 的大小和占比。
jmap
jmap
打印出 Java 进程内存中 Object 的情况,或者将 JVM 中的堆以二进制输出成文本,命令内容如下:
使用 jmap -heap 8825
查看当前堆的使用信息:
[root@wupx ~]# jmap -heap 8825 Attaching to process ID 8825, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.201-b09 using thread-local object allocation. Parallel GC with 10 thread(s) Heap