JVM性能调优工具

JPS

JPS(JVM processs Status Tool)

作用:列出正在运行的虚拟机进程,并显示虚拟机执行主类(main函数所在的类)名称以及进程的本地虚拟机唯一ID

虽然功能单一但是使用频率最高的JDK命令行工具。

对于本地虚拟机来说,唯一ID与操作系统的进程ID是一致的。使用Windows任务管理器或者unix的PS也可以查询到虚拟机进程的唯一ID,但如果同时启用多个虚拟机,无法根据进程名称定位时,只有依赖JPS命令显示主类的功能(比如我启动了很多java程序,但任务管理器中无法体现和区分)

命令格式

jps [options][hostid]

参数解释options

-q:显示进程ID
-m:显示进程ID主类名称,以及传入main方法的参数
-l:显示进程ID,主类全名
-v:显示进程ID,主类名称,以及传入jvm的参数
-V:显示进程ID,主类名称
-mlvV可以任意组合使用

第二个hostid

主机或者是服务器的ip,如果不指定,就认为当前主机是服务器

主义需要查看其他机器上的jvm进程,需要在待查看的 机器上启动jstatd

Jstat

JVM Statistics Monitoring Tool

作用:监视虚拟机各种运行状态信息,可以显示本地或者是远程虚拟机中的类装载,内存垃圾收集,JIT编译等运行数据

jstat [options vmid [interval[count]]] <pid>

options

jstat -class vmid :显示 ClassLoader 的相关信息;

jstat -compiler vmid :显示 JIT 编译的相关信息;

jstat -gc vmid :显示与 GC 相关的堆信息;

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

jstat -gcnew vmid :显示新生代信息;

jstat -gcnewcapcacity vmid :显示新生代大小与使用情况;

jstat -gcold vmid :显示老年代和永久代的行为统计,从jdk1.8开始,该选项仅表示老年代,因为永久代被移除了;

jstat -gcoldcapacity vmid :显示老年代的大小;

jstat -gcpermcapacity vmid :显示永久代大小,从jdk1.8开始,该选项不存在了,因为永久代被移除了;

jstat -gcutil vmid :显示垃圾收集信息;

vmid

如果是本地虚拟机进程,vmid和本地虚拟机唯一ID是一致的

如果是远程虚拟机进程,vmid的格式应该是

protocol[@hostname[:port]/servername]

interval

采样间隔,单位为为秒s或者毫秒

默认单位为毫秒,必须为正整数

制定后该jstat命令将在每个间隔产生其输出

count

要显示的样本数

不指定interval和count就只会打印一次

实战

jastat -gc 进程id

 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU       YGC     YGCT    FGC    FGCT     GCT
43520.0 43520.0  0.0    0.0   262144.0 20971.6   699392.0     0.0     4480.0 781.2  384.0   75.9       0    0.000   0      0.000    0.000
堆中幸存区的容量 幸存区使用大小 eden区的容量和使用 老年代的容量和使用 元空间的容量和使用量 压缩类空间容量使用 yongGc次数和时间 fullgc时间和次数 总次数

1.8以前就是永久代

jastat -gc gcutil 能看使用占比

Jinfo

Configuration Info ForJava

实时查看和调整虚拟机各项参数

joinfo [options] <pid>

options

no option:s输出全部的参数和系统属性

-flag name:输出对应名称的参数

-flag[+|-]name:开启或者关闭对应名称的参数

-flag name=value:设定对应名称的参数

-flags:输出全部参数

-sysprops:输出系统属性

演示

D:\code\java\test\t1>jinfo 31812
Attaching to process ID 31812, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.131-b11
Java System Properties:

java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 25.131-b11
sun.boot.library.path = C:\Program Files\Java\jdk1.8.0_131\jre\bin
java.vendor.url = http://java.oracle.com/
java.vm.vendor = Oracle Corporation
path.separator = ;
file.encoding.pkg = sun.io
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
sun.os.patch.level =
sun.java.launcher = SUN_STANDARD
user.script =
user.country = CN
user.dir = D:\code\java\test\t1
java.vm.specification.name = Java Virtual Machine Specification
intellij.debug.agent = true
java.runtime.version = 1.8.0_131-b11
java.awt.graphicsenv = sun.awt.Win32GraphicsEnvironment
os.arch = amd64
java.endorsed.dirs = C:\Program Files\Java\jdk1.8.0_131\jre\lib\endorsed
line.separator =

java.io.tmpdir = C:\Users\admin\AppData\Local\Temp\
java.vm.specification.vendor = Oracle Corporation
user.variant =
os.name = Windows 10
sun.jnu.encoding = GBK
java.library.path = C:\Program Files\Java\jdk1.8.0_131\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files\Oculus\Support\oculus-runtime;C:\Pro
gram Files (x86)\VMware\VMware Player\bin\;C:\Program Files\Java\jdk1.8.0_131\bin;C:\Program Files (x86)\VMware\VMware Workstation\bin\;C:\ProgramData\Oracle\Java\java
path;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\NVIDIA Corporati
on\NVIDIA NvDLISR;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\
v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\dotnet\;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC
\170\Tools\Binn\;C:\Program Files\nodejs\;C:\Program Files\WorldPainter;C:\Users\admin\AppData\Local\Programs\Python\Python39;C:\Users\admin\AppData\Local\Programs\Pyt
hon\Python39\Scripts;C:\Program Files (x86)\ZeroTier\One\;C:\Program Files\Git\cmd;C:\Users\admin\AppData\Local\Programs\Python\Python310\Scripts\;C:\Users\admin\AppDa
ta\Local\Programs\Python\Python310\;C:\Users\admin\AppData\Local\Microsoft\WindowsApps;C:\Users\admin\AppData\Local\Programs\Microsoft VS Code\bin;C:\Program Files\Jav
a\jdk1.8.0_131\bin;C:\zidingyi\ruanjian\apache-maven-3.5.4\bin;C:\Users\admin\.dotnet\tools;C:\zidingyi\ruanjian\phpEnv8.2.1-Green\phpEnv\php\php-7.4\;C:\zidingyi\ruan
jian\phpEnv8.2.1-Green\phpEnv\server\mysql\mysql-5.7\bin\;C:\zidingyi\ruanjian\phpEnv8.2.1-Green\phpEnv\tools\Composer\;C:\Users\admin\AppData\Roaming\npm;C:\Program F
iles\JetBrains\IntelliJ IDEA 2020.1\plugins\maven\lib\maven3\bin;C:\Users\admin\AppData\Local\Programs\Python\Python39\;;C:\phpEnv\php\php-7.4\;C:\phpEnv\server\mysql\
mysql-5.7\bin\;C:\phpEnv\tools\Composer\;.
jboss.modules.system.pkgs = com.intellij.rt
java.specification.name = Java Platform API Specification
java.class.version = 52.0
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
os.version = 10.0
user.home = C:\Users\admin
user.timezone =
java.awt.printerjob = sun.awt.windows.WPrinterJob
file.encoding = UTF-8
java.specification.version = 1.8
user.name = admin
java.class.path = C:\Program Files\Java\jdk1.8.0_131\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_131\jre\
lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\dnsns.jar;C:\Program Files\Java
\jdk1.8.0_131\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\localedata.jar;C:\Program
 Files\Java\jdk1.8.0_131\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunjce_provide
r.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_131\jre\
lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\j
fr.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\management-
agent.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.
jar;D:\code\java\test\t1\out\production\t1;C:\Program Files\JetBrains\IntelliJ IDEA 2020.1\lib\idea_rt.jar;C:\Users\admin\AppData\Local\JetBrains\IntelliJIdea2020.1\ca
ptureAgent\debugger-agent.jar
java.vm.specification.version = 1.8
sun.arch.data.model = 64
sun.java.command = test5.S37
java.home = C:\Program Files\Java\jdk1.8.0_131\jre
user.language = zh
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.windows.WToolkit
java.vm.info = mixed mode
java.version = 1.8.0_131
java.ext.dirs = C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\ext
sun.boot.class.path = C:\Program Files\Java\jdk1.8.0_131\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar;C:\Program Files\Java\jdk1.8.0_131\jre
\lib\sunrsasign.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\c
harsets.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_131\jre\classes
java.vendor = Oracle Corporation
file.separator = \
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
sun.desktop = windows
sun.cpu.isalist = amd64

VM Flags:
Non-default VM flags: -XX:CICompilerCount=12 -XX:InitialHeapSize=1073741824 -XX:MaxHeapSize=17156800512 -XX:MaxNewSize=5718933504 -XX:MinHeapDeltaBytes=524288 -XX:NewS
ize=357564416 -XX:OldSize=716177408 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+
UseParallelGC
Command line:  -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:56456,suspend=y,server=n -javaagent:C:\Users\admin\AppData\Local\JetBrains\IntelliJIdea2020.1\captu
reAgent\debugger-agent.jar -Dfile.encoding=UTF-8

Jmap

Memory Map for java

是命令多功能的命令,它可以生成java程序dump文件,也可以查看堆内对象信息,查看classloader信息以及finalizer队列

命令格式

jmap [options] <pid>

options

no option:查看进程的内存映射信息,类似solaris pmap命令

heap:显示java堆内存信息

histo[:live]:显示队列中对象的统计信息

clstats:答应类加载器信息

finalizerinfo:显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象

dump:生成堆转存储快照

jmap 的作用并不仅仅是为了获取 dump 文件,它还可以查询 finalizer 执行队列、Java 堆和永久代的详细信息,如空间使用率、当前使用的是哪种收集器等。和jinfo一样,jmap有不少功能在 Windows 平台下也是受限制的。

Jhat

jvm heap Dump Browser

与jmap搭配来使用分析jmap生成的堆转存储快照,Jhat内置了一个微型的HTTP、HTML服务器,生成dump文件的分析结果后,可以在浏览器中查看

不过一般不会使用该工具,原有有2

  1. 不会在部署应用程序的服务器上直接分析,dump文件,即时可以这样做,也劲量将dump文件拷贝到其他机器上进行分析,因为分析工作是 一个耗时且消耗资源的过程,既然都要在其他机器上进行就没有必要受到命令行工具的限制了
  2. jhat的分析功能相对来说比较捡漏,其他有较好的替代工具,比如visualVM以及Eclipse Memory Analyzer等,都更加强大

Jstack

生成虚拟机当前时刻的快照

线程快照是当前java虚拟机内每一条正在执行的方法堆栈的集合,生成快照主要目的是定位线程出现长时间停顿的原因,如线程间死锁,死循环,长时间等待外部资源等。

参数和格式

jstack[option]<pid>

-F:当线程挂起时,使用jstack -L pid 请求不被响应时,强制输出线程堆栈

-l:除堆栈外,显示关于锁的附加信息,例如ownable Synchronizers

-m:可以同时输出java以及C/C++的堆栈信息

Jconsole

JConsole 是基于 JMX 的可视化监视、管理工具。可以很方便的监视本地及远程服务器的 java 进程的内存使用情况。你可以在控制台输出console命令启动或者在 JDK 目录下的 bin 目录找到jconsole.exe然后双击启动。

查看java应用程序的运行概况,监视垃圾收集器管理的虚拟机内存(堆和元空间)的变化趋势,以及监控程序内的线程

JConsole 可以显示当前内存的详细信息。不仅包括堆内存/非堆内存的整体信息,还可以细化到 eden 区、survivor 区等的使用情况,如下图所示。

点击右边的“执行 GC(G)”按钮可以强制应用程序执行一个 Full GC。

Visual VM

VisualVM 提供在 Java 虚拟机 (Java Virutal Machine, JVM) 上运行的 Java 应用程序的详细信息。在 VisualVM 的图形用户界面中,您可以方便、快捷地查看多个 Java 应用程序的相关信息

Last modification:January 13, 2023
如果觉得我的文章对你有用,请随意赞赏