您现在的位置是:首页 > 协作开发

必知必会的JVM工具系列一,读懂会用jps、jstat、jinfo、jmap

智慧编程坊 2025-04-27【协作开发】58人已围观

简介介绍很多资料在介绍JDK命令行工具时并不是在Java8环境下,因此还在使用过时的永久区系列的参数,给一些读者造成困难。Java8使用Metaspace(元空间)代替永久区,对于64位平台,为了压缩JVM对象中的_klass指针的大小,引入了类指针压缩空间(CompressedClassPointer...

介绍

很多资料在介绍JDK命令行工具时并不是在Java8环境下,因此还在使用过时的永久区系列的参数,给一些读者造成困难。

Java8使用Metaspace(元空间)代替永久区,对于64位平台,为了压缩JVM对象中的_klass指针的大小,引入了类指针压缩空间(CompressedClassPointerSpace)。

1.JDK命令行工具

在JDK的开发包中,除了大家熟知的和外,还有一系列辅助工具。这些工具在JDk安装目录下的bin目录中。如图:

虽然乍看之下,这些工作都是exe的可执行文件。但事实上,它们只是Java程序的一层包装,其真正实现是在中。

以jps工具为例,在控制台执行jps命令和java-classpath%Java_HOME%/lib/命令是等价的,即只是这个命令的一层包装。

在学习以下命令之前,不妨使用IDEA写个不会退出的小程序,方便测试。示例代码:

;;;publicclassMain{publicstaticvoidmain(String[]args)throwsInterruptedException{while(true){(10000);//Byte[]bytes=newByte[1024];//bytes=null;//();(newSimpleDateFormat("yyyy-MM-ddhh:mm:ss").format(newDate()));}}}
1.1jps命令

命令jps用于列出java进程,直接运行jps不加任何参数,可以列出Java程序的进程ID以及Main函数等名称。

从这个输出中可以看到,当前系统中共存在4个Java应用程序,其中第一个输出jps就是jps命令本身,这个更加证明此命令本质也是一个Java程序。此外,jps还提供了一系列参数来控制它的输出内容。

参数-q指定jps只输出进程ID,而不输出类的短名称:

参数-m用于输出传递给Java进程(主函数)的参数:

参数-l用于输出主函数的完整路径:

参数-v可以显示传递给JVM的参数:

1.2jstat命令

jstat是一个可以用于观察Java应用程序运行时信息的工具。它的功能非常强大,可以通过它,查看堆信息的详细使用情况。它的基本使用语法为:

jstat-option[-t][-hlines]vmid[interval][count]

选项option可以由以下值构成:

-class:显示ClassLoader的相关信息。

-compiler:显示JIT编译的相关信息。

-gc:显示与GC相关的堆信息。

-gccapacity:显示各个代的容量及使用情况。

-gccause:显示垃圾收集相关信息(同-gcutil),同时显示最后一次或当前正在发生的垃圾收集的诱发原因。

-gcnew:显示新生代信息。

-gcnewcapacity:显示新生代大小与使用情况。

-gcold:显示老年代与永久代的信息。

-gcoldcapacity:显示老年代的大小。

-gcmetacapacity:显示元空间的大小。(在java8之前是使用-gcpermcapacity显示永久代的大小)

-gcutil:显示垃圾收集信息。

-printcompilation:输出JIT编译的方法信息。

以上选项可以输入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相关的堆信息的输出:

各项参数的含义如下:

S0C:s0(from)的大小(KB)。

S1C:s1(from)的大小(KB)。

S0U:s0(from)已使用的空间(KB)。

S1U:s1(from)已经使用的空间(KB)

EC:eden区的大小(KB)

EU:eden区已经使用的空间(KB)

OC:老年代大小(KB)

OU:老年代已经使用的空间(KB)

MC:元空间的大小(Metaspace)(KB)

MU:元空间已使用大小(KB)

CCSC:压缩类空间大小(compressedclassspace)(KB)

CCSU:压缩类空间已使用大小(KB)

YGC:新生代gc次数

YGCT:新生代gc耗时(秒)

FGC:Fullgc次数

FGCT:Fullgc耗时(秒)

GCT:gc总耗时(秒)

1.2.4-gccapacity

下例显示了各个代的信息,与-gc相比,它不仅输出了各个代的当前大小,也包含了各个代的最大值和最小值。

各参数含义:

NGCMN:新生代最小(初始化)容量(字节)

NGCMX:新生代最大容量(字节)

NGC:当前新生代容量(字节)

OGCMN:老年代最小容量(字节)

OGCMX:老年代最大容量(字节)

MCMN:metaspace(元空间)中初始化(最小)的大小(字节)

MCMX:metaspace(元空间)的最大容量(字节)

CCSMN:最小压缩类空间大小(字节)

CCSMX:最大压缩类空间大小(字节)

1.2.5-gccause

下列显示了最近一次GC的原因以及当前GC的原因:

各项参数如下:

LGCC:上次GC的原因。

GCC:当前GC的原因。

1.2.6-gcnew

-gcnew参数用于查看新生代的一些详细信息:

各项参数的含义如下:

TT:新生代对象晋升到老年代对象的年龄。

MTT:新生代对象晋升到老年代对象的年龄最大值。

DSS:所需的survivor区大小。

1.2.7-gcnewcapacity

-gcnewcapacity参数可以详细输出新生代各个区的大小信息:

各项参数的含义如下:

S0CMX:s0区的最大值(KB)。

S1CMX:s1区的最大值(KB)。

ECMX:eden区的最大值(KB)。

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回收相关信息:

各项参数如下:

S0:s0区使用的百分比。

S1:s1区使用的百分比。

E:eden区使用的百分比。

O:old区使用的百分比。

M:元空间使用的百分比。

CCS:压缩类空间使用的百分比。

1.3jinfo命令

jinfo可以用来查看正在运行的Java运行程序的扩展参数,甚至支持在运行时修改部分参数。它的基本语法为:

jinfooptionpid

其中option可以为以下信息:

-flag:打印指定java虚拟机的参数值。

-flag[+|-]name:设置或取消指定java虚拟机参数的布尔值。

-flagname=value:设置指定java虚拟机的参数的值。

在很多情况下,Java应用程序不会指定所有的JVM参数。而此时,开发人员可能不知道某一个具体的JVM参数的默认值。有了jinfo工具,开发人员可以很方便地找到JVM参数的当前值。

1)下例显示了新生代对象晋升到老年代对象的最大年龄。在应用程序运行时并没有指定这个参数,但是通过jinfo,可以查看这个参数的当前的值。

2)显示是否打印GC详细信息。

3)修改部分参数的值,下面是对PrintGCDetails参数的修改。

1.4jmap命令

jmap可以生成Java应用程序的堆快照和对象的统计信息。基本语法为:

jmap[option]vmid

option选项如下:

下例使用jmap生成PID为9440的Java应用程序的对象统计信息,并输入到文件中。

jmap-histo9440c:\

输出文件有如下结构:

可以看到,这个输出显示了内存中的实例数量和合计。

另一个更为重要的功能是得到Java程序的当前堆快照:

本例中,将应用程序的堆快照输出到E盘的文件中。之后,可以通过多种工具分析文件。比如,下文中提到的jhat工具。也可以使用VisualVM工具打开这个快照文件。

很赞哦!(86)