Fork me on Gitee

学会使用JDK工具

学会使用JDK工具

jinfo

概述: JDK自带的命令,主要有三大功能点

  • 可以用来查看正在运行的JAVA应用程序的扩展参数,包括Java System属性和JVM命令行参数
  • 可以动态的修改正在运行的JVM一些参数
  • 当系统崩溃时,jinfo可以从core文件里面知道崩溃的JAVA应用程序的配置信息

image-20250328225503914

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

image-20250329103825945

  • 查看当前进程对象是
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.

image-20250329111716048

jstat

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

image-20250329111937971

image-20250329112131911

  • 查看类装载信息
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

image-20250329113108174

获取并分析GC日志

获取方式

可以通过两种方式来获取GC日志,一种是使用命令动态查看,一种是在容器中设置相关参数打印GC日志。

  • 使用命令动态查看:jstat -gc 300 5
  • 设定JVM参数

image-20250329113709361

搞清楚JVM配置映射的堆结构

  • NewSize: 初始年轻代大小

  • MaxNewSize:最大年轻代大小

  • InitialHeapSize: 初始堆大小

  • MaxHeapSize: 最大堆大小

  • SurvivorRation: 年轻代比值 survive0+ survive1:2/10

image-20250329114113202

如何导出内存映射文件

  1. add vm参数 内存溢出自动导出
  • -XX:+HeapDumpOnOutOfMemoryError
  • -XX:HeadDumpPath=./
  1. 使用jmap命令手动导出

jmap -dump:format=b,file=/Users/zhangshao/heap.bin 1343

MAT分析内存溢出

下载MemoryAnalyzerTool(mat)

image-20250329234536187

image-20250329234558619

image-20250329234725005

image-20250329234628723

image-20250329234757486

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.

参考文档

  1. CPU 使用率飙升100%&死锁排查
posted @ 2025-03-30 21:46  shine-rainbow  阅读(93)  评论(0)    收藏  举报