JVM 性能监控工具之命令行篇

在 Java 开发过程中,性能监控和问题排查是开发者经常面临的任务。JDK 提供了一系列命令行工具,帮助开发者监控 JVM 运行状态、诊断内存泄漏、线程死锁等问题。本文将详细介绍这些工具的使用方法及其应用场景。

1 JDK性能监控工具

1.1 jps:查看虚拟机进程

jps(Java Virtual Machine Process Status Tool)是 JDK 提供的一个命令行工具,用于快速查看当前系统中正在运行的 Java 应用及其进程 ID(PID)。它的功能类似于 Linux 下的 ps 命令,但专门针对 Java 进程。通过 jps,开发者可以快速获取 Java 进程的 PID,从而为后续使用其他 JVM 工具(如 jstackjmap 等)进行诊断提供便利。

1.1.1 命令格式

jps [options] [hostid]
  • options:可选参数,用于控制输出内容。
  • hostid:可选参数,用于指定远程主机的标识符(通常用于远程监控)。

命令示例
运行 jps 命令后,输出结果可能如下:

12345 MainClass
67890 AnotherApp
54321 SpringBootApp
  • 每一行输出包含两部分:进程 ID(PID)主类名称
  • 例如,54321 SpringBootApp 表示 PID 为 54321 的进程正在运行一个名为 SpringBootApp 的 Java 应用。

1.1.2 PID 的作用

  • PID(Process ID) 是操作系统分配给每个进程的唯一标识符。
  • 通过 PID,开发者可以查看进程的详细信息,或者使用 kill 命令终止进程。
  • 例如,强制终止 PID 为 54321 的进程:
    kill -9 54321
    

    注意kill -9 会强制终止进程,可能导致数据丢失或应用异常退出,生产环境中需谨慎使用。

1.1.3 常用选项

选项描述
-q只输出进程 ID,忽略主类信息。
-l输出主类的全名,如果进程是通过 JAR 包启动的,则输出 JAR 文件的完整路径。
-m输出虚拟机进程启动时传递给主类 main() 方法的参数。
-v输出虚拟机进程启动时的 JVM 参数。

示例用法

  1. 查看所有 Java 进程及其主类全名:

    jps -l
    

    输出示例:

    12345 com.example.MainClass
    67890 /path/to/AnotherApp.jar
    
  2. 查看 Java 进程的 JVM 启动参数:

    jps -v
    

    输出示例:

    12345 MainClass -Xms512m -Xmx1024m
    
  3. 只查看 Java 进程的 PID:

    jps -q
    

    输出示例:

    12345
    67890
    

1.2 jstat:查看 JVM 运行时信息

jstat(Java Virtual Machine Statistics Monitoring Tool)是 JDK 提供的一个命令行工具,用于监控 JVM 的各种运行时状态信息。它能够提供关于垃圾回收、类加载、JIT 编译等方面的详细数据,帮助开发者分析和优化 Java 应用的性能。

1.2.1 命令格式

jstat [option vmid [interval[s|ms] [count]]]
  • option:指定监控的类别,例如类加载、垃圾回收等。
  • vmid:目标 Java 进程的进程 ID(PID)。
  • interval:采样间隔时间,单位为秒(s)或毫秒(ms)。
  • count:采样次数。

1.2.2 主要选项

jstat 的选项主要分为三类:类加载、垃圾回收、运行期编译状况。以下是常用选项及其功能:

1. -class:监视类加载信息
用于监控类的加载、卸载数量、总空间以及类加载所耗费的时间。

命令示例:

jstat -class -t 75952 1000 2

输出示例:

Loaded  Bytes  Unloaded  Bytes  Time
  5000  10.5 MB      100  0.2 MB  1.23s
  5100  10.8 MB      110  0.3 MB  1.45s

字段说明:

  • Loaded:加载的类的数量。
  • Bytes:所有加载类占用的空间大小。
  • Unloaded:卸载的类的数量。
  • Time:类加载器所花费的时间。

2. -gc:监视 Java 堆状况
用于监控 Java 堆的各个区域(Eden 区、Survivor 区、老年代等)的容量、已用空间以及垃圾回收的时间和次数。

命令示例:

jstat -gc 75952 1000 2

输出示例:

 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
1024.0 1024.0  0.0    0.0    8192.0   1024.0    20480.0     1024.0   4480.0  2560.0  384.0   256.0      1    0.005     0    0.000    0.005
1024.0 1024.0  0.0    0.0    8192.0   2048.0    20480.0     1024.0   4480.0  2560.0  384.0   256.0      1    0.005     0    0.000    0.005

字段说明:

  • S0CS1C:Survivor 0 区和 Survivor 1 区的当前容量(Current)。
  • S0US1U:Survivor 0 区和 Survivor 1 区的已使用空间(Used)。
  • ECEU:Eden 区的容量和已使用空间。
  • OCOU:老年代的容量和已使用空间。
  • MCMU:元空间(Metaspace)的容量和已使用空间。
  • YGCYGCT:年轻代垃圾回收的次数和总时间。
  • FGCFGCT:老年代垃圾回收(Full GC)的次数和总时间。
  • GCT:垃圾回收的总时间。

3. -compiler:监视 JIT 编译信息
用于监控 JIT(Just-In-Time)编译器编译过的方法、耗时等信息。

命令示例:

jstat -compiler 75952 1000 2

输出示例:

Compiled Failed Invalid   Time   FailedType FailedMethod
     1000     10      5   1.23s  SomeClass  someMethod
     1050     12      6   1.45s  AnotherClass  anotherMethod

字段说明:

  • Compiled:编译的方法数量。
  • Failed:编译失败的方法数量。
  • Invalid:失效的编译方法数量。
  • Time:编译所花费的时间。

1.2.3 其他常用选项

选项描述
-gccapacity监控 Java 堆各个区域的最大、最小空间。
-gcutil监控 Java 堆各个区域的已使用空间占总空间的百分比。
-gccause-gcutil 功能相同,但额外输出导致上一次垃圾回收的原因。
-gcnew监控新生代垃圾回收情况。
-gcnewcapacity监控新生代的最大、最小空间。
-gcold监控老年代垃圾回收情况。
-gcoldcapacity监控老年代的最大、最小空间。
-printcompilation输出已经被 JIT 编译的方法。

1.3 jinfo:查看虚拟机配置

jinfo(Configuration Info for Java)是 JDK 提供的一个命令行工具,用于查看或动态调整 JVM 的各项配置参数。它的主要功能包括:

  1. 查看 JVM 参数:输出当前 Java 进程的 JVM 启动参数。
  2. 动态修改参数:在不重启应用的情况下,调整某些 JVM 参数(仅限于支持动态修改的参数)。

1.3.1 命令格式

jinfo [option] pid
  • option:可选参数,用于指定操作类型。
  • pid:目标 Java 进程的进程 ID。

1.3.2 常用选项

选项描述
-flags输出 JVM 的启动参数。
-sysprops输出 Java 系统属性(等同于 System.getProperties())。
-flag <name>查看某个特定 JVM 参数的值。
-flag [+|-]<name>动态启用或禁用某个 JVM 参数。

1.3.3 示例用法

  1. 查看 JVM 启动参数:

    jinfo -flags 88952
    

    输出示例:

    Attaching to process ID 88952, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 11.0.12+7-LTS
    Non-default VM flags: -XX:CICompilerCount=4 -XX:InitialHeapSize=268435456 -XX:MaxHeapSize=4294967296 ...
    Command line:  -Xms256m -Xmx4G
    
  2. 查看 Java 系统属性:

    jinfo -sysprops 88952
    

    输出示例:

    Attaching to process ID 88952, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 11.0.12+7-LTS
    java.runtime.name = Java(TM) SE Runtime Environment
    java.vm.version = 11.0.12+7-LTS
    user.country = CN
    ...
    
  3. 查看特定 JVM 参数的值:

    jinfo -flag MaxHeapSize 88952
    

    输出示例:

    -XX:MaxHeapSize=4294967296
    
  4. 动态修改 JVM 参数:

    jinfo -flag +PrintGCDetails 88952
    

    注意:并非所有 JVM 参数都支持动态修改,具体取决于 JVM 实现和参数类型。

1.3.4 常见问题及解决方法

问题:jinfo 命令无法执行成功,提示无法附加到进程。

可能原因:

  1. JDK 版本不一致:jinfo 工具的版本与目标 Java 进程使用的 JDK 版本不一致。
  2. 权限不足:当前用户没有权限访问目标进程。
  3. JDK 版本过旧:某些旧版本 JDK 可能存在兼容性问题。

解决方法:

  1. 确保 JDK 版本一致:

    • 使用与目标 Java 进程相同的 JDK 版本的 jinfo 工具。
    • 例如,如果目标进程使用 JDK 11,则确保 jinfo 也来自 JDK 11。
  2. 使用管理员权限运行:

    • 在 Linux/macOS 上,尝试使用 sudo 提升权限:
      sudo jinfo -flags <pid>
      
  3. 升级 JDK 版本:

    • 如果使用的是较旧的 JDK 版本,尝试升级到较新的稳定版本(如 JDK 11 或 JDK 17)。

示例:

# 使用 JDK 11 的 jinfo 查看进程信息
/usr/lib/jvm/jdk-11/bin/jinfo -flags 10025

1.4 jmap:导出堆快照

jmap(Java Memory Map)是 JDK 提供的一个命令行工具,用于生成 Java 堆转储快照(heap dump),并查看堆内存的详细信息。堆转储文件包含了 JVM 堆中所有对象的信息,包括类、属性、引用等,是分析内存泄漏和优化内存使用的重要工具。

1.4.1 命令格式

jmap [option] vmid
  • option:指定操作类型。
  • vmid:目标 Java 进程的进程 ID(PID)。

1.4.2 常用选项

选项描述
-dump生成 Java 堆转储快照(heap dump)。
-finalizerinfo显示在 F-Queue 中等待 Finalizer 线程执行 finalize 方法的对象。(仅限 Linux 平台)
-heap显示 Java 堆的详细信息,包括垃圾回收器类型、参数配置、分代情况等。(仅限 Linux 平台)
-histo显示堆中对象的统计信息,包括类、实例数量、占用内存大小等。
-F当目标进程对 -dump 选项无响应时,强制生成堆转储快照。(仅限 Linux 平台)

1.4.3 示例用法

  1. 生成堆转储快照:

    jmap -dump:format=b,file=heap.hprof 10025
    
    • format=b:指定文件格式为二进制。
    • file=heap.hprof:指定输出文件名为 heap.hprof
    • 10025:目标 Java 进程的 PID。

    说明:

    • 生成的堆转储文件(heap.hprof)可以使用工具(如 Eclipse MAT、VisualVM)进行分析。
  2. 查看堆中对象统计信息:

    jmap -histo 10025
    

    输出示例:

    num     #instances         #bytes  class name
    ---------------------------------------------
       1:        100000      10000000  java.lang.String
       2:         50000       2000000  java.util.HashMap$Node
       3:         30000       1200000  java.lang.Object
    ...
    
    • #instances:类的实例数量。
    • #bytes:实例占用的内存大小。
    • class name:类名。
  3. 显示 Java 堆详细信息:

    jmap -heap 10025
    

    输出示例:

    Attaching to process ID 10025, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 11.0.12+7-LTS
    
    using thread-local object allocation.
    Parallel GC with 4 thread(s)
    
    Heap Configuration:
       MinHeapFreeRatio = 40
       MaxHeapFreeRatio = 70
       MaxHeapSize      = 4294967296 (4096.0MB)
       NewSize          = 10485760 (10.0MB)
       MaxNewSize       = 4294967296 (4096.0MB)
       OldSize          = 20971520 (20.0MB)
       NewRatio         = 2
       SurvivorRatio    = 8
       ...
    
  4. 强制生成堆转储快照:

    jmap -F -dump:format=b,file=heap.hprof 10025
    
    • 当目标进程无响应时,使用 -F 选项强制生成堆转储。

1.4.4 堆转储文件分析工具

生成的堆转储文件(如 heap.hprof)可以使用以下工具进行分析:

  1. Eclipse MAT(Memory Analyzer Tool)

    • 功能强大,支持内存泄漏分析、对象依赖关系查看等。
    • 下载地址:Eclipse MAT
  2. VisualVM

    • JDK 自带的图形化工具,支持堆转储分析和性能监控。
    • 启动命令:jvisualvm
  3. JProfiler

    • 商业工具,提供全面的性能分析和堆转储分析功能。
    • 官网:JProfiler

1.5 jstack:跟踪 Java 堆栈

jstack 是 JDK 提供的一个命令行工具,用于打印 JVM 中某个进程的线程堆栈信息(通常称为 threaddump 或 javacore 文件)。它常用于诊断应用程序中的线程问题,如线程死锁、死循环或长时间等待。

1.5.1 命令格式

jstack [option] vmid
  • option:可选参数,用于控制输出内容。
  • vmid:目标 Java 进程的进程 ID(PID)。

1.5.2 常用选项

选项描述
-F当正常输出的请求不被响应时,强制输出线程堆栈。
-l除了堆栈信息外,显示关于锁的附加信息(如持有的锁、等待的锁等)。
-m如果调用的是本地方法(Native Method),显示 C/C++ 的堆栈信息。

1.5.3 示例用法

  1. 打印线程堆栈信息:

    jstack 10025
    

    输出示例:

    "main" #1 prio=5 os_prio=0 tid=0x00007f8b4c009000 nid=0x2703 waiting on condition [0x00007f8b4d0f0000]
       java.lang.Thread.State: WAITING (parking)
            at sun.misc.Unsafe.park(Native Method)
            - parking to wait for  <0x000000076b70c4b8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
            at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
            at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
            at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
            at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
            at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
            at com.example.DeadLockDemo.lambda$main$0(DeadLockDemo.java:10)
            at com.example.DeadLockDemo$$Lambda$1/1096979270.run(Unknown Source)
            at java.lang.Thread.run(Thread.java:748)
    
  2. 打印线程堆栈信息及锁信息:

    jstack -l 10025
    

    输出示例:

    "Thread-1" #12 prio=5 os_prio=0 tid=0x00007f8b4c0b8000 nid=0x2705 waiting for monitor entry [0x00007f8b4b6f0000]
       java.lang.Thread.State: BLOCKED (on object monitor)
            at com.example.DeadLockDemo.lambda$main$1(DeadLockDemo.java:25)
            - waiting to lock <0x000000076b70c4b8> (a java.lang.Object)
            - locked <0x000000076b70c4c8> (a java.lang.Object)
            at com.example.DeadLockDemo$$Lambda$2/1324119927.run(Unknown Source)
            at java.lang.Thread.run(Thread.java:748)
    
    "Thread-0" #11 prio=5 os_prio=0 tid=0x00007f8b4c0b7000 nid=0x2704 waiting for monitor entry [0x00007f8b4b7f0000]
       java.lang.Thread.State: BLOCKED (on object monitor)
            at com.example.DeadLockDemo.lambda$main$0(DeadLockDemo.java:15)
            - waiting to lock <0x000000076b70c4c8> (a java.lang.Object)
            - locked <0x000000076b70c4b8> (a java.lang.Object)
            at com.example.DeadLockDemo$$Lambda$1/1096979270.run(Unknown Source)
            at java.lang.Thread.run(Thread.java:748)
    
  3. 强制打印线程堆栈信息:

    jstack -F 10025
    
    • 当目标进程无响应时,使用 -F 选项强制输出线程堆栈。

1.5.4 诊断死锁问题

以下是一个简单的死锁示例程序:

class DeadLockDemo {
    private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();

    public static void main(String[] args) {
        new Thread(() -> {
            synchronized (lock1) {
                System.out.println("线程1获取到了锁1");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock2) {
                    System.out.println("线程1获取到了锁2");
                }
            }
        }).start();

        new Thread(() -> {
            synchronized (lock2) {
                System.out.println("线程2获取到了锁2");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock1) {
                    System.out.println("线程2获取到了锁1");
                }
            }
        }).start();
    }
}

运行结果:
程序运行后卡住,无法继续执行。

使用 jstack 诊断死锁:

jstack -l <pid>

输出示例:

Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x00007f8b4c0b8000 (object 0x000000076b70c4b8, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x00007f8b4c0b7000 (object 0x000000076b70c4c8, a java.lang.Object),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
        at com.example.DeadLockDemo.lambda$main$1(DeadLockDemo.java:25)
        - waiting to lock <0x000000076b70c4b8> (a java.lang.Object)
        - locked <0x000000076b70c4c8> (a java.lang.Object)
        at com.example.DeadLockDemo$$Lambda$2/1324119927.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)
"Thread-0":
        at com.example.DeadLockDemo.lambda$main$0(DeadLockDemo.java:15)
        - waiting to lock <0x000000076b70c4c8> (a java.lang.Object)
        - locked <0x000000076b70c4b8> (a java.lang.Object)
        at com.example.DeadLockDemo$$Lambda$1/1096979270.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)

说明:

  • jstack 输出了死锁的详细信息,包括哪些线程在等待哪些锁,以及锁的持有者。

1.6 jcmd:多功能命令

jcmd 是 JDK 提供的一个多功能命令行工具,集成了 jstackjmapjstatjinfo 等工具的功能。它能够收集堆转储、生成 JVM 和 Java 应用程序的性能数据,以及动态更改某些 Java 运行时参数。jcmd 的强大之处在于它可以通过单一命令完成多种任务,简化了 JVM 监控和诊断的操作。

1.6.1 命令格式

jcmd <pid | main class> <command ... | PerfCounter.print | -f file>
  • pid:目标 Java 进程的进程 ID。
  • main class:目标 Java 应用的主类名。
  • command:要执行的操作或命令。
  • PerfCounter.print:打印性能计数器信息。
  • -f file:从文件中读取命令并执行。

1.6.2 常用功能

  1. 列出所有 Java 应用:

    jcmd -l
    

    输出示例:

    10025 com.example.MainClass
    20036 org.apache.catalina.startup.Bootstrap
    
  2. 查看支持的命令:

    jcmd 10025 help
    

    输出示例:

    The following commands are available:
    JFR.stop
    JFR.start
    JFR.dump
    JFR.check
    VM.native_memory
    VM.check_commercial_features
    VM.unlock_commercial_features
    ManagementAgent.stop
    ManagementAgent.start_local
    ManagementAgent.start
    Thread.print
    GC.class_histogram
    GC.heap_dump
    GC.run_finalization
    GC.run
    VM.uptime
    VM.flags
    VM.system_properties
    VM.command_line
    VM.version
    help
    
  3. 查看 JVM 参数:

    jcmd 10025 VM.flags
    

    输出示例:

    -XX:CICompilerCount=4 -XX:InitialHeapSize=268435456 -XX:MaxHeapSize=4294967296 ...
    
  4. 打印线程信息:

    jcmd 10025 Thread.print
    

    输出示例:

    "main" #1 prio=5 os_prio=0 tid=0x00007f8b4c009000 nid=0x2703 waiting on condition [0x00007f8b4d0f0000]
       java.lang.Thread.State: WAITING (parking)
            at sun.misc.Unsafe.park(Native Method)
            - parking to wait for  <0x000000076b70c4b8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
            at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
            at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
            at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
            at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
            at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
            at com.example.DeadLockDemo.lambda$main$0(DeadLockDemo.java:10)
            at com.example.DeadLockDemo$$Lambda$1/1096979270.run(Unknown Source)
            at java.lang.Thread.run(Thread.java:748)
    
  5. 生成堆转储文件:

    jcmd 10025 GC.heap_dump filename=heap.hprof
    

    说明:

    • 生成的堆转储文件(heap.hprof)可以使用工具(如 Eclipse MAT、VisualVM)进行分析。
  6. 打印性能计数器信息:

    jcmd 10025 PerfCounter.print
    

    输出示例:

    java.ci.totalTime=123456
    java.cls.loadedClasses=5000
    java.cls.unloadedClasses=100
    ...
    
  7. 查看系统属性:

    jcmd 10025 VM.system_properties
    

    输出示例:

    java.runtime.name=Java(TM) SE Runtime Environment
    java.vm.version=11.0.12+7-LTS
    user.country=CN
    ...
    
  8. 查看 JVM 启动时间:

    jcmd 10025 VM.uptime
    

    输出示例:

    1234.567 seconds
    

1.6.3 主要选项

选项描述补充说明
help打印帮助信息。示例:jcmd help
ManagementAgent.stop停止 JMX Agent。
ManagementAgent.start_local开启本地 JMX Agent。
ManagementAgent.start开启 JMX Agent。
Thread.print打印线程信息,相当于 jstack支持 -l 参数打印锁信息。
PerfCounter.print打印性能计数器信息,相当于 jstat -J-Djstat.showUnsupported=true -snap
GC.class_histogram打印堆中对象统计信息,相当于 jmap -histo
GC.heap_dump生成堆转储文件,相当于 jmap -dump:format=b,file=xxx.bin
GC.run_finalization运行 finalize 方法,相当于 System.runFinalization()
GC.run触发垃圾回收,相当于 System.gc()
VM.uptime打印 JVM 启动时间,以秒为单位。支持 -date 参数打印当前时间。
VM.flags打印 JVM 参数,相当于 jinfo -flags支持 -all 参数输出全部信息。
VM.system_properties打印系统属性,相当于 jinfo -sysprops
VM.command_line打印 JVM 启动命令,相当于 `jinfo -syspropsgrep command`。
VM.version打印 JVM 版本信息,相当于 `jinfo -syspropsgrep version`。

2 操作系统工具

除了 JDK 自带的工具,操作系统也提供了一些命令行工具,帮助开发者监控系统资源使用情况。

2.1 top:显示系统整体资源使用情况

top 是一个常用的命令行工具,用于实时监控系统的整体资源使用情况,包括 CPU、内存、进程等。它能够帮助开发者快速识别系统中占用资源较高的进程,从而进行性能分析和优化。

2.1.1 命令格式

top
  • 默认情况下,top 会实时更新显示信息,按 Ctrl + C 退出。

2.1.2 输出解析

top 的输出分为两部分:统计信息进程信息

1. 统计信息

统计信息部分提供了系统的整体资源使用情况,主要包括以下内容:

  1. 进程和线程信息:

    Processes: 500 total, 10 running, 490 sleeping, 2000 threads
    
    • Processes:总进程数。
    • running:正在运行的进程数。
    • sleeping:睡眠的进程数。
    • threads:总线程数。
  2. 负载均衡和 CPU 使用率:

    Load Avg: 4.02, 3.89, 3.29  CPU usage: 6.97% user, 3.54% sys, 89.47% idle
    
    • Load Avg:过去 1 分钟、5 分钟和 15 分钟的平均系统负载。负载值大于 CPU 核心数时,表示系统相对繁忙。
    • CPU usage
      • user:用户进程占用的 CPU 百分比。
      • sys:系统内核占用的 CPU 百分比。
      • idle:CPU 空闲百分比。
  3. 共享库内存使用:

    SharedLibs: 100M resident, 50M data, 10M linkedit.
    
    • 显示操作系统加载的共享库(如动态链接库)的内存使用情况。
  4. 内存区域使用:

    MemRegions: 5000 total, 100M resident, 50M private, 200M shared.
    
    • 显示系统内存区域的使用情况,包括代码、数据、堆、栈等。
  5. 物理内存使用:

    PhysMem: 30G used (3018M wired), 1547M unused.
    
    • used:已使用的物理内存。
    • wired:被锁定在内存中的部分(不可被交换到磁盘)。
    • unused:未使用的物理内存。
  6. 虚拟内存信息:

    VM: 50G vsize, 20G framework vsize, 10G swapins, 5G swapouts.
    
    • vsize:虚拟内存总量。
    • swapins:从磁盘交换到内存的数据量。
    • swapouts:从内存交换到磁盘的数据量。
  7. 网络和硬盘信息:

    Networks: packets: 22655692/19G in, 19180791/11G out.
    Disks: 14866544/288G read, 15176739/251G written.
    
    • Networks:网络接收和发送的数据包数量及大小。
    • Disks:硬盘读取和写入的次数及数据量。

2. 进程信息

进程信息部分列出了系统中各个进程的资源使用情况,主要字段包括:

字段描述
PID进程 ID,是操作系统分配给进程的唯一标识符。
COMMAND进程的命令名或命令行。
%CPU进程占用的 CPU 使用率。
TIME进程使用的 CPU 时间总计,单位为 1/100 秒。
MEM进程使用的物理内存和虚拟内存大小,单位为 KB。

示例:

PID    COMMAND          %CPU  TIME     MEM
10025  java             10.5  00:10.23 1024M
20036  chrome           5.2   00:05.12 512M

2.1.3 常用操作

  1. 按 CPU 使用率排序:

    • 运行 top 后,按 P 键。
  2. 按内存使用率排序:

    • 运行 top 后,按 M 键。
  3. 刷新间隔设置:

    • 运行 top 后,按 d 键,然后输入刷新间隔(秒)。
  4. 退出 top

    • Ctrl + Cq 键。

2.1.4 Windows 替代工具

在 Windows 系统中,可以使用以下命令查看进程信息:

  1. tasklist

    tasklist
    

    输出示例:

    Image Name                     PID Session Name        Session#    Mem Usage
    ========================= ======== ================ =========== ============
    java.exe                      10025 Console                    1     102,400 K
    chrome.exe                    20036 Console                    1     512,000 K
    
  2. 任务管理器:

    • 通过 Ctrl + Shift + Esc 打开任务管理器,查看进程和资源使用情况。

2.2 vmstat:监控内存和 CPU

vmstat(Virtual Memory Statistics)是 Linux 系统上的一款性能监控工具,用于统计系统的 CPU、内存、swap、I/O 等资源的使用情况。它能够帮助开发者快速了解系统的整体性能状况,识别资源瓶颈。

2.2.1 命令格式

vmstat [options] [delay [count]]
  • options:可选参数,用于指定输出内容。
  • delay:采样间隔时间,单位为秒。
  • count:采样次数。

2.2.2 基本用法

  1. 实时监控:

    vmstat 1 3
    
    • 每秒采样一次,共采样 3 次。
  2. 持续监控:

    vmstat 1
    
    • 每秒采样一次,持续输出,按 Ctrl + C 退出。

2.2.3 输出解析

vmstat 的输出分为两部分:系统资源概览详细统计信息

示例输出:

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 100000  20000 300000    0    0    10    20  100  200  5  2 93  0  0
 0  0      0  98000  21000 310000    0    0    15    25  110  210  6  1 93  0  0

字段说明:

  1. procs(进程):

    • r:等待运行的进程数。
    • b:处于不可中断睡眠状态的进程数。
  2. memory(内存):

    • swpd:使用的虚拟内存大小(swap)。
    • free:空闲的物理内存大小。
    • buff:用作缓冲区的内存大小。
    • cache:用作缓存的内存大小。
  3. swap(交换分区):

    • si:每秒从磁盘读入 swap 的数据量(KB)。
    • so:每秒写入磁盘的 swap 数据量(KB)。
  4. io(I/O):

    • bi:每秒从块设备读入的数据量(KB)。
    • bo:每秒写入块设备的数据量(KB)。
  5. system(系统):

    • in:每秒的中断次数。
    • cs:每秒的上下文切换次数。
  6. cpu(CPU):

    • us:用户进程占用的 CPU 百分比。
    • sy:系统内核占用的 CPU 百分比。
    • id:CPU 空闲百分比。
    • wa:等待 I/O 操作的 CPU 百分比。
    • st:虚拟机占用的 CPU 百分比。

2.2.4 常用选项

选项描述
-a显示活跃和非活跃内存。
-d显示磁盘统计信息。
-s显示内存统计信息。
-p显示指定分区的 I/O 统计信息。
-t在输出中增加时间戳。

示例用法

  1. 显示活跃和非活跃内存:

    vmstat -a 1 3
    

    输出示例:

    procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
     r  b   swpd   free  inact active   si   so    bi    bo   in   cs us sy id wa st
     1  0      0 100000 200000 300000    0    0    10    20  100  200  5  2 93  0  0
    
  2. 显示磁盘统计信息:

    vmstat -d 1 3
    

    输出示例:

    disk- ------------reads------------ ------------writes----------- -----IO------
           total merged sectors      ms  total merged sectors      ms    cur    sec
    sda    1000    200  100000     500    500    100   50000     300      0      0
    
  3. 显示内存统计信息:

    vmstat -s
    

    输出示例:

        1000000  total memory
        800000   used memory
        200000   active memory
        100000   inactive memory
        50000    free memory
    
  4. 显示指定分区的 I/O 统计信息:

    vmstat -p /dev/sda1 1 3
    

    输出示例:

    sda1  reads  read sectors  writes  requested writes
         1000    100000        500     50000
    

2.3 iostat:监控 IO 使用

iostat(Input/Output Statistics)是 Linux 系统上的一款性能监控工具,用于统计 CPU 使用情况和磁盘的 I/O 信息。它能够帮助开发者分析系统的 I/O 性能,识别磁盘瓶颈。

2.3.1 命令格式

iostat [options] [interval [count]]
  • options:可选参数,用于指定输出内容。
  • interval:采样间隔时间,单位为秒。
  • count:采样次数。

2.3.2 输出解析

iostat 的输出分为两部分:CPU 使用情况磁盘 I/O 统计

示例输出:

Linux 5.4.0-42-generic (hostname) 	09/01/2023 	_x86_64_	(4 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.23    0.00    1.23    0.12    0.00   93.42

Device             tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda               1.23        10.00        20.00     100000     200000

字段说明:

  1. CPU 使用情况:

    • %user:用户进程占用的 CPU 百分比。
    • %nice:低优先级用户进程占用的 CPU 百分比。
    • %system:系统内核占用的 CPU 百分比。
    • %iowait:等待 I/O 操作的 CPU 百分比。
    • %steal:虚拟机被其他虚拟机占用的 CPU 百分比。
    • %idle:CPU 空闲百分比。
  2. 磁盘 I/O 统计:

    • tps:每秒传输次数(Transfers Per Second)。
    • kB_read/s:每秒读取的数据量(KB)。
    • kB_wrtn/s:每秒写入的数据量(KB)。
    • kB_read:读取的总数据量(KB)。
    • kB_wrtn:写入的总数据量(KB)。

2.3.3 常用选项

选项描述
-c只显示 CPU 使用情况。
-d只显示磁盘 I/O 统计信息。
-x显示扩展的磁盘 I/O 统计信息。
-p显示指定磁盘分区的 I/O 统计信息。
-t在输出中增加时间戳。

示例用法

  1. 查看 CPU 和所有磁盘设备的基本 I/O 统计信息:

    iostat
    

    输出示例:

    avg-cpu:  %user   %nice %system %iowait  %steal   %idle
               5.23    0.00    1.23    0.12    0.00   93.42
    
    Device             tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
    sda               1.23        10.00        20.00     100000     200000
    
  2. 查看磁盘 I/O 统计信息,每 2 秒更新一次:

    iostat -d 2
    

    输出示例:

    Device             tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
    sda               1.23        10.00        20.00     100000     200000
    sda               1.50        15.00        25.00     150000     250000
    
  3. 查看扩展的磁盘 I/O 统计信息:

    iostat -x
    

    输出示例:

    Device            r/s     w/s     rkB/s     wkB/s   rrqm/s   wrqm/s  %rrqm  %wrqm  r_await  w_await  svctm  %util
    sda              0.50    0.73     10.00     20.00     0.00     0.00   0.00   0.00    1.23     2.34    0.56   0.12
    

    扩展字段说明:

    • r/s:每秒读取次数。
    • w/s:每秒写入次数。
    • rkB/s:每秒读取的数据量(KB)。
    • wkB/s:每秒写入的数据量(KB)。
    • rrqm/s:每秒合并的读取请求数。
    • wrqm/s:每秒合并的写入请求数。
    • %rrqm:读取请求合并的百分比。
    • %wrqm:写入请求合并的百分比。
    • r_await:读取请求的平均等待时间(毫秒)。
    • w_await:写入请求的平均等待时间(毫秒)。
    • svctm:I/O 请求的平均服务时间(毫秒)。
    • %util:磁盘的繁忙程度(百分比)。
  4. 只查看 CPU 使用情况:

    iostat -c
    

    输出示例:

    avg-cpu:  %user   %nice %system %iowait  %steal   %idle
               5.23    0.00    1.23    0.12    0.00   93.42
    
  5. 查看指定磁盘分区的 I/O 统计信息:

    iostat -p sda1
    

    输出示例:

    Device             tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
    sda1              1.23        10.00        20.00     100000     200000
    

2.4 netstat:监控网络使用

netstat(Network Statistics)是一个常用的命令行工具,用于监控和显示网络相关信息,包括网络连接、路由表、接口统计等。它能够帮助开发者分析网络状态,诊断网络问题。

2.4.1 命令格式

netstat [options]
  • options:可选参数,用于指定输出内容。

2.4.2 常用选项

选项描述
-a显示所有连接和侦听端口。
-t显示 TCP 连接。
-u显示 UDP 连接。
-n以数字形式显示地址和端口号(不解析主机名和服务名)。
-r显示路由表。
-l显示侦听中的套接字。
-p显示与套接字关联的进程 ID 和程序名称。
-s显示网络协议的统计信息。
-c持续输出网络信息,按 Ctrl + C 退出。

2.4.3 输出解析

netstat 的输出通常包括以下几个方面的信息:

  1. 网络连接:

    • 显示活动的或监听的套接字连接,包括协议、本地地址和端口、远程地址和端口、连接状态等。
  2. 路由表:

    • 显示网络路由表,包括目的地址、网关、子网掩码、使用的接口等。

示例用法

  1. 显示所有连接和侦听端口:

    netstat -a
    

    输出示例:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State
    tcp        0      0 0.0.0.0:22             0.0.0.0:*               LISTEN
    tcp        0      0 192.168.1.100:22       192.168.1.200:54321     ESTABLISHED
    udp        0      0 0.0.0.0:68             0.0.0.0:*
    
  2. 显示 TCP 连接:

    netstat -t
    

    输出示例:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State
    tcp        0      0 192.168.1.100:22       192.168.1.200:54321     ESTABLISHED
    
  3. 显示 UDP 连接:

    netstat -u
    

    输出示例:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State
    udp        0      0 0.0.0.0:68             0.0.0.0:*
    
  4. 以数字形式显示地址和端口号:

    netstat -n
    

    输出示例:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State
    tcp        0      0 192.168.1.100:22       192.168.1.200:54321     ESTABLISHED
    
  5. 显示路由表:

    netstat -r
    

    输出示例:

    Kernel IP routing table
    Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
    default         192.168.1.1     0.0.0.0         UG        0 0          0 eth0
    192.168.1.0     *               255.255.255.0   U         0 0          0 eth0
    
  6. 显示侦听中的套接字:

    netstat -l
    

    输出示例:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State
    tcp        0      0 0.0.0.0:22             0.0.0.0:*               LISTEN
    
  7. 显示与套接字关联的进程 ID 和程序名称:

    netstat -p
    

    输出示例:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    tcp        0      0 192.168.1.100:22       192.168.1.200:54321     ESTABLISHED 1234/sshd
    
  8. 显示网络协议的统计信息:

    netstat -s
    

    输出示例:

    Ip:
       1000 total packets received
       0 forwarded
       0 incoming packets discarded
       1000 incoming packets delivered
       1000 requests sent out
    
  9. 持续输出网络信息:

    netstat -c
    
    • 持续输出网络信息,按 Ctrl + C 退出。

3 总结

JDK 提供的性能监控工具和操作系统命令行工具是开发者排查问题、优化性能的利器。掌握这些工具的使用方法,能够帮助开发者在面对内存泄漏、线程死锁等问题时,快速定位并解决问题。希望本文的介绍能够为开发者提供有价值的参考。

4 思维导图

在这里插入图片描述

5 参考链接

JVM 性能监控工具之命令行篇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/945158.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用IDEA远程debug服务器上的jar包

仅用于测试环境调试&#xff0c;debug会阻塞 如生产jar包叫 test.jar &#xff0c;部署的IP为10.184.136.18&#xff0c;端口为9999&#xff0c;idea的项目为local-network&#xff0c;照如下配置即可&#xff0c;仅红色部分需替换 弄完之后&#xff0c;打开debug&#xff0c;…

【SQL Server】教材数据库(3)

接着教材数据库&#xff08;1&#xff09;的内容&#xff0c;完成下列查询。 1 查询订购高等教育出版社教材的学生姓名 2 查询比所有高等教育出版社的图书都贵的图书信息 3 列出每位学生姓名、订购教材书名、价格。 1、嵌套查询&#xff1a;use jiaocai select student.nam…

你有哪些Deep Learning(RNN、CNN)调参的经验?

在深度学习的实践中&#xff0c;调参是一项既艺术又科学的工作。它不仅需要理论知识的支撑&#xff0c;还需要大量的实践经验。以下是一些在RNN和CNN模型调参中积累的经验&#xff0c;希望对正在这个领域摸索的朋友们有所帮助。 1. 从成熟的开源项目开始 对于初学者来说&…

Unity3D仿星露谷物语开发11之添加Scenary Fader

1、目标 当角色移动到草/树的后面时&#xff0c;因为草/树层级优先级大于等于角色&#xff0c;导致角色无法全部展示。 如下图所示&#xff0c;草遮挡了一半的角色&#xff0c;而树则遮挡了全部的角色。 我们希望当角色走到草/树的后面时&#xff0c;草/树能够改变透明度&…

021-spring-springmvc

比较重要的部分 比较重要的部分 比较重要的部分 关于组件的部分 这里以 RequestMappingHandlerMapping 为例子 默认的3个组件是&#xff1a; org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping org.springframework.web.servlet.mvc.method.annotation.Requ…

关于 PCB线路板细节锣槽问题 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/144783817 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

无人机快速巡检、森林、电力、水利大大节省人力成本,降低风险事故

无人机在快速巡检、森林、电力、水利等领域的应用&#xff0c;确实大大节省了人力成本&#xff0c;并有效降低了风险事故。以下是对这些应用的详细分析&#xff1a; 一、无人机快速巡检 无人机快速巡检技术以其高效性、安全性和精准性&#xff0c;在众多领域展现出了巨大的应…

生态碳汇涡度相关监测与通量数据分析实践技术应用

基于MATLAB语言、以实践案例为主&#xff0c;提供所有代码、原理与操作结合 1、以涡度通量塔的高频观测数据为例&#xff0c;基于MATLAB开展上机操作&#xff1a; 2、涡度通量观测基本概况&#xff1a;观测技术方法、数据获取与预处理等 3、涡度通量数据质量控制&#xff1a…

【Lua之·Lua与C/C++交互·Lua CAPI访问栈操作】

系列文章目录 文章目录 前言一、概述1.1 Lua堆栈 二、栈操作2.1 基本的栈操作2.2 入栈操作函数2.3 出栈操作函数2.4 既入栈又出栈的操作函数2.5 栈检查与类型转换函数2.5 获取表数据 三、实例演示总结 前言 Lua是一种轻量级的、高性能的脚本语言&#xff0c;经常被用于游戏开发…

安装OpenGauss数据库流程

一、安装完欧拉系统将yum上传至本地&#xff1a; 创建文件 mkdir /media/iso 挂载镜像 mount /dev/sr0 /media/iso 未通网情况&#xff0c;删除自带的yum&#xff0c;创建一个新的 cd /etc/yum.repos.d/ rm -r 加yum文件名称 &#xff08;删除自带yum&#xff09; v…

Go语言zero项目服务恢复与迁移文档

## 一. 服务器环境配置 在迁移和配置 项目时&#xff0c;首先需要确保服务器环境正确配置。以下是配置步骤&#xff1a; ### 1. 安装 Go 语言环境 首先&#xff0c;确保 Go 语言环境已经安装&#xff0c;并且配置正确。执行以下步骤&#xff1a; # 下载 Go 语言安装包 wge…

【 Sonarqube】可视化Java项目单元测试覆盖率统计框架搭建

一、项目背景&#xff1a; 一个小公司的朋友反应他们那边Java项目单元测试有&#xff0c;但还没有可视化统计覆盖率数据&#xff0c;没法统计就不能直观的看到单测的覆盖率&#xff0c;Java的覆盖率统计框架还是比较成熟&#xff0c;部署起来也不是很难&#xff0c;下面我们逐…

使用ForceBindIP绑定应用到指定IP

前言 使用ForceBindIP工具&#xff0c;用户可以轻松地将特定应用程序绑定到指定的IP地址&#xff0c;从而确保应用程序的网络连接通过指定的网络适配器进行。通过在命令提示符下运行ForceBindIP并指定IP地址和应用程序的完整路径&#xff0c;用户能够控制应用程序的网络流量&a…

Webpack学习笔记(6)

首先搭建一个基本的webpack环境&#xff1a; 执行npm init -y&#xff0c;创建pack.json&#xff0c;保存安装包的一些信息 执行npm install webpack webpack-cli webpack-dev-server html-webpack-plugin -D&#xff0c;出现node_modules和package-lock.json。 1.source-Ma…

【学生管理系统】element ui级联菜单bug

级联后端 通过父id来进行查询 GetMapping("/{parentId}")public BaseResult findAllByParentId(PathVariable("parentId") String parentId){//1 根据父id查询所有城市QueryWrapper<TbCity> queryWrapper new QueryWrapper<>();queryWrapper.…

关于无线AP信道调整的优化(锐捷)

目录 一、信道优化的基本原则二、2.4G频段信道优化三、5G频段信道优化四、信道优化代码具体示例五、其他优化措施 一、信道优化的基本原则 信道优化旨在减少信道间的干扰&#xff0c;提高网络覆盖范围和信号质量。基本原则包括&#xff1a; 1. 选择合适的信道&#xff1a;根据…

Ubuntu 下使用命令行将 U 盘格式化为 ext4、FAT32 和 exFAT 的详细教程

Ubuntu 下使用命令行将 U 盘格式化为 ext4、FAT32 和 exFAT 的详细教程 作者&#xff1a;Witheart更新时间&#xff1a;20241228 本教程将详细介绍如何将 U 盘格式化为 ext4、FAT32 和 exFAT 文件系统&#xff0c;同时包括如何安装必要工具&#xff08;如 exfat-utils&#x…

【设计与实现】基于Bootstrap的地方旅游管理系统的设计与实现

目录 第一章 绪论 1.1 研究现状 1.2 设计原则 1.3 研究内容 第四章 系统设计 4.1系统结构设计 4.2系统顺序图设计 4.3数据库设计 第五章 系统实现 5.1登录模块的实现 第一章 绪论 1.1 研究现状 时代的发展&#xff0c;我们迎来了数字化信息时代&#xff0c;它正在渐…

【MySQL高级】索引

MySQL高级课程简介 序号010203041基本硬件知识体系结构应用优化MySQL 常用工具2索引存储引擎查询缓存优化MySQL 日志3视图优化SQL步骤内存管理及优化MySQL 主从复制4存储过程和函数索引使用MySQL锁问题5触发器SQL优化常用SQL技巧 1. 基本硬件知识 1.1 计算机工作原理 1.中央处…

【Redis】:初识Redis

1.1 盛赞 Redis Redis 是⼀种基于键值对&#xff08;key-value&#xff09;的 NoSQL 数据库&#xff0c;与很多键值对数据库不同的是&#xff0c;Redis 中的值可以是由 string&#xff08;字符串&#xff09;、hash&#xff08;哈希&#xff09;、list&#xff08;列表&#xf…