【JVM】常用命令

一、前言

Java虚拟机(JVM)是Java程序运行的基础设施,它负责将Java字节码转换为本地机器代码并执行。在开发过程中,我们经常需要使用一些命令来监控和管理JVM的性能和状态。本文将详细介绍6个常用的JVM命令:jps、jstat、jmap、jhat、jstack和jinfo。

二、命令:jps

jps 命令用于列出当前系统中所有正在运行的Java进程及其主类名。它可以帮助我们快速找到我们需要调试或监控的Java进程。

命令格式:

jps [options] [hostid]

option参数:

  • -l : 输出主类全名或jar路径

  • -q : 只输出LVMID

  • -m : 输出JVM启动时传递给main()的参数

  • -v : 输出JVM启动时显示指定的JVM参数

使用示例:

bash 复制代码
[root@hope ~]# jps -v
11072 Jps -Denv.class.path=.:/home/jdk-11.0.12/lib:/home/jdk-11.0.12/jre/lib: -Dapplication.home=/home/jdk-11.0.12 -Xms8m -Djdk.module.main=jdk.jcmd
27219 Elasticsearch -Xshare:auto -Des.networkaddress.cache.ttl=60 -Des.networkaddress.cache.negative.ttl=10 -XX:+AlwaysPreTouch -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -XX:-OmitStackTraceInFastThrow -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dio.netty.recycler.maxCapacityPerThread=0 -Dio.netty.allocator.numDirectArenas=0 -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Djava.locale.providers=SPI,COMPAT -Xms1g -Xmx1g -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -Djava.io.tmpdir=/tmp/elasticsearch-13871375846251346330 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=data -XX:ErrorFile=logs/hs_err_pid%p.log -Xlog:gc*,gc+age=trace,safepoint:file=logs/gc.log:utctime,pid,tags:filecount=32,filesize=64m -XX:MaxDirectMemorySize=536870912 -Des.path.home=/usr/local/elasticsearch-7.9.3 -Des.path.conf=/usr/local/elasticsearch-7.9.3/config -Des.distribution.flavor=default -Des.distribution.type=tar -Des.bundled_jdk=true

三、命令:jstat

jstat 命令用于收集和报告关于Java虚拟机(JVM)的各种统计信息。这些信息可以帮助我们了解JVM的性能状况,例如垃圾回收情况、内存使用情况等。

命令格式:

jstat 【options】 <PID> 【interval】 【count】

命令参数说明:

  • Options,一般使用 -gcutil 或 -gc 查看gc 情况

  • pid,当前运行的 java进程号

  • interval,间隔时间,单位为秒或者毫秒

  • count,打印次数,如果缺省则打印无数次

Options 参数如下:

  • -gc:统计 jdk gc时 heap信息,以使用空间字节数表示

  • -gcutil:统计 gc时, heap情况,以使用空间的百分比表示

  • -class:统计 class loader行为信息

  • -compile:统计编译行为信息

  • -gccapacity:统计不同 generations(新生代,老年代,持久代)的 heap容量情况

  • -gccause:统计引起 gc的事件

  • -gcnew:统计 gc时,新生代的情况

  • -gcnewcapacity:统计 gc时,新生代 heap容量

  • -gcold:统计 gc时,老年代的情况

  • -gcoldcapacity:统计 gc时,老年代 heap容量

  • -gcpermcapacity:统计 gc时, permanent区 heap容量

使用示例1:

jstat -gc 15 5000 5

每5秒一次显示进程号为15的java进程的GC情况,每5S生成异常,一共生成5次。

我可以计算出如下核心数据:

  • 第一个幸存区的大小S0C:300M

  • 第二个幸存区的大小S1C:300M

  • 伊甸园区的大小EC:2400M

  • 老年代大小OC:5000M

  • 方法区大小MC:236M

  • 年轻代垃圾回收消耗时间YGCT:531.164(单位?)

  • 老年代垃圾回收消耗时间FGCT:6.874(单位?)

我们再看输出的GC日志:

bash 复制代码
Heap before GC invocations=6641 (full 10):
 par new generation   total 2764800K, used 2492979K [0x00000005cc000000, 0x0000000687800000, 0x0000000687800000)
  eden space 2457600K, 100% used [0x00000005cc000000, 0x0000000662000000, 0x0000000662000000)
  from space 307200K,  11% used [0x0000000674c00000, 0x0000000676e8cc90, 0x0000000687800000)
  to   space 307200K,   0% used [0x0000000662000000, 0x0000000662000000, 0x0000000674c00000)
 concurrent mark-sweep generation total 5120000K, used 3462278K [0x0000000687800000, 0x00000007c0000000, 0x00000007c0000000)
 Metaspace       used 209218K, capacity 229352K, committed 241360K, reserved 1265664K
  class space    used 20538K, capacity 24038K, committed 26120K, reserved 1048576K
343501.719: [GC (Allocation Failure) 343501.719: [ParNew: 2492979K->24333K(2764800K), 0.0261186 secs] 5955257K->3486700K(7884800K), 0.0262698 secs] [Times: user=0.05 sys=0.01, real=0.03 secs]

可以计算出如下核心数据:

  • 第一个幸存区的大小S0C:300M

  • 第二个幸存区的大小S1C:300M

  • 伊甸园区的大小EC:2400M

  • 老年代大小OC:从这里计算不出来

  • 方法区大小MC:从这里计算不出来

  • GC耗时:30ms

配置的JAVA_OPTS参数如下:

-Xmx8000M -Xms8000M -Xmn3000M -XX:PermSize=1000M -XX:MaxPermSize=1000M -Xss256K -XX:+DisableExplicitGC -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSClassUnloadingEnabled -XX:LargePageSizeInBytes=128M -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=69 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+PrintClassHistogram -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Xloggc:/home/work/logs/applogs/gc.log -javaagent:/home/work/app/prometheus/jmx_prometheus_javaagent-0.12.0.jar=3010:/home/work/app/prometheus/jmx-exporter.yml

使用示例2:

jstat -gccapacity 15

同-gc,不过还会输出Java堆各区域使用到的最大、最小空间

bash 复制代码
NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC 
819200.0 819200.0 819200.0 273024.0 273024.0 273152.0  5324800.0  5324800.0  5324800.0  5324800.0      0.0 1251328.0 223560.0      0.0 1048576.0  22716.0    174     8
bash 复制代码
NGCMN Minimum new generation capacity (KB).
NGCMX Maximum new generation capacity (KB).
NGC Current new generation capacity (KB).
S0C Current survivor space 0 capacity (KB).
S1C Current survivor space 1 capacity (KB).
EC Current eden space capacity (KB).
OGCMN Minimum old generation capacity (KB).
OGCMX Maximum old generation capacity (KB).
OGC Current old generation capacity (KB).
OC Current old space capacity (KB).
PGCMN Minimum permanent generation capacity (KB).
PGCMX Maximum Permanent generation capacity (KB).
PGC Current Permanent generation capacity (KB).
PC Current Permanent space capacity (KB).
YGC Number of Young generation GC Events.
FGC Number of Full GC Events.

四、命令:jmap

jmap命令用于生成Java堆内存快照文件(heap dump)。这些文件可以用于分析内存泄漏问题,或者进行性能调优。

命令格式:

jmap 【options】 <pid>

options参数解释 :

  • no options 如果使用不带选项参数的jmap打印共享对象映射, 将会打印目标虚拟机中加载的每个对象的起始地址、映射大小及共享对象文件的路径全称。(很占资源, 一般不会使用)

  • -heap:打印java heap 摘要

  • -histo[:live] :打印堆中的java对象统计信息

  • -clstats :打印类加载器统计信息

  • -finalizerinfo:打印在f-queue中等待执行finalizer方法的对象

  • -dump:生成java堆的dump文件, dump-options:

  • live :只转储存活的对象,如果没有指定则转储所有对象

  • format=b:二进制格式

  • file=[Path] :将文件转储到指定文件中

使用示例1:

将java堆中存活的对象信息转储到/dump.bin文件中

jmap -dump:live,format=b,file=/dump.bin 0813

我们来看一下堆信息:

jmap -heap 0813

输出:

bash 复制代码
Attaching to process ID 11666, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.25-b02
 
using thread-local object allocation.
Parallel GC with 4 thread(s)
 
Heap Configuration: //堆内存初始化配置
   MinHeapFreeRatio  = 0 //对应jvm启动参数-XX:MinHeapFreeRatio设置JVM堆最小空闲比率(default 40)
   MaxHeapFreeRatio  = 100 //对应jvm启动参数 -XX:MaxHeapFreeRatio设置JVM堆最大空闲比率(default 70)
   MaxHeapSize= 1073741824 (1024.0MB) //对应jvm启动参数-XX:MaxHeapSize=设置JVM堆的最大大小
   NewSize    = 22020096 (21.0MB) //对应jvm启动参数-XX:NewSize=设置JVM堆的新生代的默认大小
   MaxNewSize = 357564416 (341.0MB) //对应jvm启动参数-XX:MaxNewSize=设置JVM堆的新生代的最大大小
   OldSize    = 45088768 (43.0MB) //对应jvm启动参数-XX:OldSize=<value>:设置JVM堆的老年代的大小
   NewRatio   = 2 //对应jvm启动参数-XX:NewRatio=:新生代和老生代的大小比率
   SurvivorRatio     = 8 //对应jvm启动参数-XX:SurvivorRatio=设置新生代中Eden区与Survivor区的大小比值
   MetaspaceSize     = 21807104 (20.796875MB) // 元数据区大小
   CompressedClassSpaceSize = 1073741824 (1024.0MB) //类压缩空间大小
   MaxMetaspaceSize  = 17592186044415 MB //元数据区最大大小
   G1HeapRegionSize  = 0 (0.0MB) //G1垃圾收集器每个Region大小
 
Heap Usage: //堆内存使用情况
PS Young Generation 
Eden Space: //Eden区内存分布
   capacity = 17825792 (17.0MB) //Eden区总容量
   used     = 12704088 (12.115562438964844MB) //Eden区已使用
   free     = 5121704 (4.884437561035156MB) //Eden区剩余容量
   71.26801434685203% used //Eden区使用比率
 
From Space: //其中一个Survivor区的内存分布
   capacity = 2097152 (2.0MB)
   used     = 1703936 (1.625MB)
   free     = 393216 (0.375MB)
   81.25% used
To Space: //另一个Survivor区的内存分布
   capacity = 2097152 (2.0MB)
   used     = 0 (0.0MB)
   free     = 2097152 (2.0MB)
   0.0% used
PS Old Generation
   capacity = 52428800 (50.0MB) //老年代容量
   used     = 28325712 (27.013504028320312MB) //老年代已使用
   free     = 24103088 (22.986495971679688MB) //老年代空闲
   54.027008056640625% used //老年代使用比率
 
15884 interned Strings occupying 2075304 bytes.

输出存活对象信息 :

jmap -histo:live 0813 | more

使用示例2:

jmap -histo:live 10 | more

打印堆的对象统计,包括对象数、内存大小等等 (因为在dump:live前会进行full gc,如果带上live则只统计活对象,因此不加live的堆大小要大于加live堆的大小 ),仅打印前10行。

bash 复制代码
num     #instances         #bytes  class name
----------------------------------------------
   1:        938552      113143448  [C
   2:        983711       31478752  java.util.HashMap$Node
   3:        930339       22328136  java.lang.String
   4:         61854       21628224  [B
   5:        215981       19006328  java.lang.reflect.Method
   6:        200183       18164992  [Ljava.lang.Object;
   7:        121341       16297048  [Ljava.util.HashMap$Node;
   8:        511306       12919376  [Ljava.lang.String;
   9:        169168        9391000  [I
  10:        165488        6619520  java.util.LinkedHashMap$Entry
  11:        131563        6315024  org.hibernate.hql.internal.ast.tree.Node
  12:        122202        5865696  java.util.HashMap
  13:        320105        5121680  java.lang.Integer
  14:        204087        4898088  java.util.ArrayList
  15:        138888        4444416  java.util.concurrent.ConcurrentHashMap$Node
  ... ...

xml class name是对象类型,说明如下:

bash 复制代码
B  byte
C  char
D  double
F  float
I  int
J  long
Z  boolean
[数组,如[I表示int[]
[L+类名 其他对象

五、命令:jhat

jhat 用来分析jmap生成dump文件的命令, jhat内置了应用服务器,可以通过网页查看dump文件分析结果,jhat一般用于离线分析。

命令格式:

jhap 【options】 【dumpfile】

option参数解释:

  • -stack false :关闭对象分配调用堆栈的跟踪

  • -refs false:关闭对象引用的跟踪

  • -port:HTTP服务器端口, 默认是7000

  • -debug:debug级别

  • -version:分析报告版本

使用示例:

jhat dump.hprof

执行结果:

可以通过Http://localhost:7000访问:

具体排查时需要结合代码,观察是否大量应该被回收的对象在一直被引用或者是否有占用内存特别大的对象无法被回收。一般情况,会down到客户端用工具来分析。

六、命令:jstack

jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。

如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。

另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。

命令格式:

jstack 【options】 【pid】

options参数解释:

  • -F :当使用jstack无响应时,强制输出线程堆栈

  • -m:同时输出java堆栈和c/c++ 堆栈信息

  • -l :除了输出堆栈信息外, 显示关于锁的附加信息

使用示例:

jstack -l 5073|more

执行结果:

七、命令:jinfo

jinfo命令用于显示Java虚拟机(JVM)的配置信息,包括系统属性、Java版本、可用的JVM选项等。这可以帮助我们了解JVM的配置和使用情况。

命令格式:

jinfo 【options】 <pid>

options参数解释:

  • no options :输出所有的系统属性和参数

  • -flag :打印指定名称的参数

  • -flag [+|-] :打开或关闭参数

  • -flag = 设置参数值

  • -flags 打印所有参数

  • -sysprops 打印系统配置

使用示例:

bash 复制代码
# 查看jvm参数和系统配置
jinfo 1234
jinfo -flags 1234
jinfo -sysprops 1234
 
# 查看打印GC日志参数
jinfo -flag PrintGC 1234
jinfo -flag PrintGCDetail 1234
 
# 打开/关闭 GC日志
jinfo -flag +PrintGC 1234
jinfo -flag -PrintGCDetail 1234
 
# 设置或自改参数值
jinfo -flag -Xms10m 1234
相关推荐
憨子周1 小时前
2M的带宽怎么怎么设置tcp滑动窗口以及连接池
java·网络·网络协议·tcp/ip
霖雨2 小时前
使用Visual Studio Code 快速新建Net项目
java·ide·windows·vscode·编辑器
SRY122404192 小时前
javaSE面试题
java·开发语言·面试
Fiercezm3 小时前
JUC学习
java
无尽的大道3 小时前
Java 泛型详解:参数化类型的强大之处
java·开发语言
ZIM学编程3 小时前
Java基础Day-Sixteen
java·开发语言·windows
我不是星海3 小时前
1.集合体系补充(1)
java·数据结构
P.H. Infinity3 小时前
【RabbitMQ】07-业务幂等处理
java·rabbitmq·java-rabbitmq
爱吃土豆的程序员3 小时前
java XMLStreamConstants.CDATA 无法识别 <![CDATA[]]>
xml·java·cdata
2401_857610034 小时前
多维视角下的知识管理:Spring Boot应用
java·spring boot·后端