学会使用JDK工具
学会使用JDK工具
jinfo
概述: JDK自带的命令,主要有三大功能点
- 可以用来查看正在运行的JAVA应用程序的扩展参数,包括Java System属性和JVM命令行参数
- 可以动态的修改正在运行的JVM一些参数
- 当系统崩溃时,jinfo可以从core文件里面知道崩溃的JAVA应用程序的配置信息

public class JavaSystemProperties {
public static void main(String[] args) {
//打印所有的JAVA系统熟属性
Properties properties = System.getProperties();
properties.list(System.out);
System.out.println("=====================================");
//获取特性的 JAVA系统属性,key不存在则返回null
// jre主目录
System.out.println(System.getProperty("java.home"));
// 用于搜索本机库的 JRE
System.out.println(System.getProperty("java.library.path"));
//JRE扩展库路径
System.out.println(System.getProperty("java.ext.dirs"));
//JRE类路径
System.out.println(System.getProperty("java.class.path"));
//JAVA版本
System.out.println(System.getProperty("java.class.version"));
// 未设置的JAVA系统属性
System.out.println(System.getProperty("none property"));
}
}
- 查看是否开启了打印GC日志的功能
jinfo -flag PrintGC 2797
-XX:-PrintGC
- 动态开启对应参数,
jinfo -flag +PrintGC 2797
- 打印堆dump路径
jinfo -flag HeapDumpPath 2797
-XX:HeapDumpPath=
- 设置HeapDump路径
jinfo -flag HeapDumpPath=/tmp/pid.txt 2797
- 查看详细JVM参数
jinfo -flags 2797
VM Flags:
-XX:CICompilerCount=4 -XX:ConcGCThreads=2 -XX:G1ConcRefinementThreads=8 -XX:G1EagerReclaimRemSetThreshold=16 -XX:G1HeapRegionSize=2097152 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=268435456 -XX:+ManagementServer -XX:MarkStackSize=4194304 -XX:MaxHeapSize=4294967296 -XX:MaxNewSize=2575302656 -XX:MinHeapDeltaBytes=2097152 -XX:MinHeapSize=8388608 -XX:NonProfiledCodeHeapSize=0 -XX:-ProfileInterpreter -XX:ProfiledCodeHeapSize=0 -XX:SoftMaxHeapSize=4294967296 -XX:TieredStopAtLevel=1 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseG1GC -XX:-UseNUMA -XX:-UseNUMAInterleaving
JMap
概念:JDK自带的分析工具,输出进程,核心文件的共享对象内存或者堆内存的相关信息。常见的应用方向有
-
Java堆的详细信息:包括使用的GC算法,堆的配置信息和各个内存区域内存的使用情况
-
显示对重对象的统计信息,会包括每一个Java类,对象的数量,内存使用大小,类名称
-
打印正等候回收的对象的信息
-
生成堆转储快照dump文件,使用jhat以html的方式查看
-
打印堆的详细信息
jmap --heap --pid 1343
# 如果是java11及以上
jhsdb jmap --heap --pid 1343
- 打印当前有多少个Java类,使用内存情况
jmap -histo:live 1343

- 查看当前进程对象是
jmap -finalizerinfo 1343
No instances waiting for finalization found
- 生成堆转储文件dump文件,是当前运行状态的快照信息
jmap -dump:live,format=b,file=/Users/zhangshao/heap.bin 1343
Dumping heap to /Users/zhangshao/heap.bin ...
Heap dump file created [43916284 bytes in 0.190 secs]
- 查看dump文件
jhat $HOME/heap.bin
Reading from /Users/zhangshao/heap.bin...
Dump file created Sat Mar 29 10:41:54 CST 2025
Snapshot read, resolving...
Resolving 468919 objects...
Chasing references, expect 93 dots..............................................
...............................................
Eliminating duplicate references.............................................................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

jstat
概念:用于监控虚拟机各种运行状态信息的命令工具,可以显示虚拟机进程中的类装载、内存、垃圾回收、JIT编译等运行数据。


- 查看类装载信息
jstat -class 1343
Loaded Bytes Unloaded Bytes Time
10325 19763.1 95 131.4 3.78
- loaded 加载类数量
- Bytes 加载类大小
- Unloaded 卸载类数量
- Bytes 卸载类大小
- Time 装载和卸载总消耗时间
- 编译统计信息
jstat -compiler 1343
Compiled Failed Invalid Time FailedType FailedMethod
5625 2 0 1.99 1 org/aspectj/weaver/World isExpendable
- 查看GC信息
# 每300毫秒打印GC信息,打印5次
jstat -gc 1343 300 5

获取并分析GC日志
获取方式
可以通过两种方式来获取GC日志,一种是使用命令动态查看,一种是在容器中设置相关参数打印GC日志。
- 使用命令动态查看:jstat -gc
300 5 - 设定JVM参数

搞清楚JVM配置映射的堆结构
NewSize: 初始年轻代大小
MaxNewSize:最大年轻代大小
InitialHeapSize: 初始堆大小
MaxHeapSize: 最大堆大小
SurvivorRation: 年轻代比值 survive0+ survive1:2/10

如何导出内存映射文件
- add vm参数 内存溢出自动导出
- -XX:+HeapDumpOnOutOfMemoryError
- -XX:HeadDumpPath=./
- 使用jmap命令手动导出
jmap -dump:format=b,file=/Users/zhangshao/heap.bin 1343
MAT分析内存溢出





jstack
jstack是JVM自带的Java堆栈跟踪工具,它用于打印出给定的java进程ID、core file、远程调试服务的Java堆栈信息.
Usage:
jstack [-l][-e] <pid>
(to connect to running process)
Options:
-l long listing. Prints additional information about locks
-e extended listing. Prints additional information about threads
-? -h --help -help to print this help message
public class DeathLock {
private static Lock lock1 = new ReentrantLock();
private static Lock lock2 = new ReentrantLock();
public static void deathLock() {
Thread t1 = new Thread() {
@Override
public void run() {
try {
lock1.lock();
System.out.println(Thread.currentThread().getName() + " get the lock1");
Thread.sleep(1000);
lock2.lock();
System.out.println(Thread.currentThread().getName() + " get the lock2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t2 = new Thread() {
@Override
public void run() {
try {
lock2.lock();
System.out.println(Thread.currentThread().getName() + " get the lock2");
Thread.sleep(1000);
lock1.lock();
System.out.println(Thread.currentThread().getName() + " get the lock1");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
//设置线程名字,方便分析堆栈信息
t1.setName("mythread-kevin");
t2.setName("mythread-lucy");
t1.start();
t2.start();
}
public static void main(String[] args) {
deathLock();
}
}
运行后输出:
mythread-kevin get the lock1
mythread-lucy get the lock2
使用jps及jstack定位
jps
976 DeathLock
1047 Jps
671 Main
975 Launcher
jstack -l 976
Java stack information for the threads listed above:
===================================================
"mythread-kevin":
at jdk.internal.misc.Unsafe.park(java.base@17.0.14/Native Method)
- parking to wait for <0x000000070fcab7a8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(java.base@17.0.14/LockSupport.java:211)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base@17.0.14/AbstractQueuedSynchronizer.java:715)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base@17.0.14/AbstractQueuedSynchronizer.java:938)
at java.util.concurrent.locks.ReentrantLock$Sync.lock(java.base@17.0.14/ReentrantLock.java:153)
at java.util.concurrent.locks.ReentrantLock.lock(java.base@17.0.14/ReentrantLock.java:322)
at com.imooc.engineering.guide.gc.DeathLock$1.run(DeathLock.java:18)
"mythread-lucy":
at jdk.internal.misc.Unsafe.park(java.base@17.0.14/Native Method)
- parking to wait for <0x000000070fcab778> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(java.base@17.0.14/LockSupport.java:211)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base@17.0.14/AbstractQueuedSynchronizer.java:715)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base@17.0.14/AbstractQueuedSynchronizer.java:938)
at java.util.concurrent.locks.ReentrantLock$Sync.lock(java.base@17.0.14/ReentrantLock.java:153)
at java.util.concurrent.locks.ReentrantLock.lock(java.base@17.0.14/ReentrantLock.java:322)
at com.imooc.engineering.guide.gc.DeathLock$2.run(DeathLock.java:32)
Found 1 deadlock.

浙公网安备 33010602011771号