很多资料在介绍JDK命令行工具时并不是在Java8环境下,因此还在使用过时的永久区系列的参数,给一些读者造成困难。
Java8使用Metaspace(元空间)代替永久区,对于64位平台,为了压缩JVM对象中的_klass指针的大小,引入了类指针压缩空间(Compressed Class Pointer Space) 。
在JDK的开发包中,除了大家熟知的java.exe和javac.exe外,还有一系列辅助工具。这些工具在JDk安装目录下的bin目录中。如图:
虽然乍看之下,这些工作都是exe的可执行文件。但事实上,它们只是Java程序的一层包装,其真正实现是在 tools.jar 中。
以jps工具为例,在控制台执行jps命令和java -classpath %Java_HOME%/lib/tools.jar sun.tools.jps.Jps命令是等价的,即jps.exe只是这个命令的一层包装。
在学习以下命令之前,不妨使用IDEA写个不会退出的小程序,方便测试。示例代码:
package cn.zyzpp.jConsole;import java.text.SimpleDateFormat;import java.util.Date;public class Main { public static void main(String[] args) throws InterruptedException { while (true){ Thread.sleep(10000); //Byte[] bytes = new Byte[1024]; //bytes = null; //System.gc(); System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date())); } }}
命令jps用于列出java进程,直接运行jps不加任何参数,可以列出Java程序的进程ID以及Main函数等名称。
从这个输出中可以看到,当前系统中共存在4个Java应用程序,其中第一个输出jps就是jps命令本身,这个更加证明此命令本质也是一个Java程序。此外,jps还提供了一系列参数来控制它的输出内容。
参数-q指定jps只输出进程ID,而不输出类的短名称:
参数-m用于输出传递给Java进程(主函数)的参数:
参数 -l用于输出主函数的完整路径:
参数 -v可以显示传递给JVM的参数:
jstat是一个可以用于观察Java应用程序运行时信息的工具。它的功能非常强大,可以通过它,查看堆信息的详细使用情况。它的基本使用语法为:
jstat - [-t] [-h] [] []
选项option可以由以下值构成:
以上选项可以输入 jstat -options 查看。
-t 参数可以在输出信息前加一个 Timestamp 列,显示程序的运行时间。
-h 参数可以在周期性数据输出时,输出多少行数据后,跟着输出一个表头信息。
vmid 参数就是Java进程id。
interval 参数用于指定输出统计数据的周期,单位为毫秒。
count 用于指定一共输出多少次数据。
示例
1.2.1 -class
输出java进程13516的ClassLoader相关信息。每秒钟统计一次信息,一共输出2次:
在-class的输出中,Loaded 表示载入了类的数量,Bytes表示载入类的合计大小(KB),Unloaded 表示卸载类的数量,第2个Bytes表示卸载类的大小,Time表示在加载和卸载类上所花的时间。
1.2.2 -compiler
下例显示了查看JIT编译的信息:
Compiled 表示编译任务执行的次数,Failed表示编译失败的次数,Invalid 表示编译不可用的次数,Time 表示编译后的总耗时,FailedType 表示最后一次编译失败的类型,FailedMethod 表示最后一次编译失败的类名和方法名。
1.2.3 -gc
下例显示了与GC相关的堆信息的输出:
各项参数的含义如下:
1.2.4 -gccapacity
下例显示了各个代的信息,与-gc相比,它不仅输出了各个代的当前大小,也包含了各个代的最大值和最小值。
各参数含义:
1.2.5 -gccause
下列显示了最近一次GC的原因以及当前GC的原因:
各项参数如下:
1.2.6 -gcnew
-gcnew 参数用于查看新生代的一些详细信息:
各项参数的含义如下:
1.2.7 -gcnewcapacity
-gcnewcapacity 参数可以详细输出新生代各个区的大小信息:
各项参数的含义如下:
1.2.8 -gcold
-gcold 可以用于展现老年代GC的概况。
1.2.9 -gcoldcapacity
-gcoldcapacity 用于展现老年代的容量信息:
1.2.10 -gcmetacapacity与-gcpermcapacity
-gcpermcapacity 用于展示永久区的使用情况,但是在Java8环境下使用会报错找不到。因为java8的永久区被元空间取而代之。所以要使用 -gcmetacapacity:
1.2.11 -gcutil
-gcutil 用于展示GC回收相关信息:
各项参数如下:
jinfo 可以用来查看正在运行的Java运行程序的扩展参数,甚至支持在运行时修改部分参数。它的基本语法为:
jinfo
其中option可以为以下信息:
1)下例显示了新生代对象晋升到老年代对象的最大年龄。在应用程序运行时并没有指定这个参数,但是通过jinfo,可以查看这个参数的当前的值。
2)显示是否打印GC详细信息。
3)修改部分参数的值,下面是对PrintGCDetails参数的修改。
jmap 可以生成Java应用程序的堆快照和对象的统计信息。基本语法为:
jmap [option] vmid
option 选项如下:
下例使用jmap生成PID为9440的Java应用程序的对象统计信息,并输入到 s.txt 文件中。
jmap -histo 9440 >c:s.txt
输出文件有如下结构:
可以看到,这个输出显示了内存中的实例数量和合计。
另一个更为重要的功能是得到Java程序的当前堆快照:
本例中,将应用程序的堆快照输出到E盘的heap.bin文件中。之后,可以通过多种工具分析文件。比如,下文中提到的jhat工具。也可以使用 Visual VM工具打开这个快照文件。