Java常用工具使用方法

JMAP:

jmap 是 Java 提供的一个工具,用于生成 Java 堆内存的快照,并帮助分析堆的使用情况。它常用于诊断 Java 应用程序中的内存问题,如内存泄漏或性能问题。

jmap 常用步骤

  1. 查看所有 Java 进程

    使用 jmap 前,首先可以查看当前机器上所有运行的 Java 进程,获取目标进程的 PID(进程ID)。

    bash 复制代码
    jps

    该命令会列出当前系统中所有运行的 Java 进程及其进程 ID。例如:

    bash 复制代码
    12345 MyJavaApp

    这里 12345 是进程 ID。

  2. 生成堆转储(Heap Dump)

    使用 jmap 生成堆转储文件(heap dump),这是分析堆内存使用情况的重要工具。

    bash 复制代码
    jmap -dump:live,format=b,file=heapdump.hprof <PID>
    • -dump:live:表示仅导出存活对象的堆信息。
    • format=b:表示以二进制格式导出堆信息。
    • file=heapdump.hprof:指定导出的堆转储文件的路径和名称。
    • <PID>:替换为目标 Java 进程的进程 ID。

    生成的堆转储文件 heapdump.hprof 可以使用分析工具(如 Eclipse Memory Analyzer Tool、VisualVM 等)进一步分析。

  3. 查看堆内存使用情况

    可以使用 jmap 查看堆内存的基本使用情况,比如查看堆的总大小、各个区域的大小、内存使用情况等。

    bash 复制代码
    jmap -heap <PID>

    输出示例:

    ini 复制代码
    Heap Configuration:
        MinHeapFreeRatio         = 40
        MaxHeapFreeRatio         = 70
        MaxHeapSize              = 2147483648 (2048.0MB)
        NewSize                  = 83886080 (80.0MB)
        MaxNewSize               = 2147483648 (2048.0MB)
        OldSize                  = 134217728 (128.0MB)
        NewRatio                 = 2
        SurvivorRatio            = 8
        MetaspaceSize            = 218103808 (208.0MB)

    该命令显示堆内存的配置和使用情况,例如年轻代、老年代、元空间的大小等。

  4. 查看堆中对象的详细信息

    使用 jmap -histo 可以查看堆中类的实例数量和内存占用。

    bash 复制代码
    jmap -histo <PID>

    输出会列出堆内所有类的实例和占用的内存。例如:

    yaml 复制代码
    num     #instances         #bytes  class name
    ----------------------------------------------
    1:          9876         1556789  [C
    2:         12345         9876543  java.lang.String
    3:          4321         1234567  java.util.ArrayList
    ...

    这有助于查找占用大量内存的类和对象。

  5. 查看类的详细内存使用情况

    使用 jmap -F 可以强制执行一些操作,例如强制进行堆转储或强制查看堆内存。

    bash 复制代码
    jmap -F -heap <PID>

    该命令在分析堆使用情况时可能有所帮助。

注意事项

  • 权限问题 :通常需要以管理员权限运行 jmap,或者确保当前用户有足够的权限访问目标 Java 进程的内存。
  • 性能开销:生成堆转储或频繁查看堆内存会引入额外的性能开销,因此在生产环境中使用时应小心。
  • JVM参数 :某些 JVM 参数(例如 -XX:+HeapDumpOnOutOfMemoryError)也能帮助在发生内存溢出时自动生成堆转储文件。

JSRACK

jstack 是 Java 提供的一个工具,用于生成 Java 应用程序的线程堆栈(Thread Dump)。它可以帮助你查看线程的执行状态,诊断死锁、线程挂起或性能问题等。

jstack 常用步骤

  1. 查看 Java 进程

    在使用 jstack 之前,首先需要查看当前机器上所有正在运行的 Java 进程,获取目标进程的 PID(进程 ID)。可以使用 jps 命令列出所有 Java 进程。

    bash 复制代码
    jps

    该命令会列出当前系统中所有运行的 Java 进程及其进程 ID。例如:

    bash 复制代码
    12345 MyJavaApp

    这里 12345 是 Java 应用程序的进程 ID(PID)。

  2. 生成线程堆栈(Thread Dump)

    使用 jstack 命令可以生成 Java 应用程序的线程堆栈信息。

    bash 复制代码
    jstack <PID>
    • <PID>:替换为目标 Java 进程的进程 ID。

    该命令会输出所有线程的堆栈信息,包括每个线程的当前状态、正在执行的方法等。

    输出示例:

    bash 复制代码
    "main" #1 prio=5 os_prio=0 tid=0x00007fbfc4004800 nid=0x4b03 waiting on condition [0x00007fbf88cfd000]
       java.lang.Thread.State: WAITING (on object monitor)
          at java.lang.Object.wait(Native Method)
          - waiting on <0x00000000f1cd9800> (a java.lang.Object)
          at java.lang.Object.wait(Object.java:502)
          at java.lang.Thread.join(Thread.java:1238)
          at com.example.MyApp.main(MyApp.java:15)

    该输出显示了线程的状态、调用栈以及锁的状态等信息。

  3. 将线程堆栈输出保存到文件

    如果堆栈信息较长,你可以将其输出保存到文件中,便于进一步分析。

    bash 复制代码
    jstack <PID> > threaddump.txt

    这样线程堆栈信息就会被保存到 threaddump.txt 文件中,之后可以用文本编辑器查看或分析。

  4. 生成死锁(Deadlock)信息

    jstack 还可以用来检查死锁。死锁发生时,两个或多个线程互相等待对方释放资源,导致程序无法继续执行。使用 -l 选项可以显示死锁信息。

    bash 复制代码
    jstack -l <PID>

    如果存在死锁,输出将包括死锁相关的信息,像下面这样:

    bash 复制代码
    Found one Java-level deadlock:
    =============================
    "Thread-1" #15 prio=5 os_prio=0 tid=0x00007f12c480b800 nid=0x1e03 waiting for monitor entry
       at com.example.MyClass.method1(MyClass.java:42)
       - waiting to lock <0x000000078e5ab5a0> (a java.lang.Object)
       at com.example.MyClass.method2(MyClass.java:56)
       - locked <0x000000078e5ab5a0> (a java.lang.Object)
    "Thread-2" #16 prio=5 os_prio=0 tid=0x00007f12c480c000 nid=0x1e04 waiting for monitor entry
       at com.example.MyClass.method2(MyClass.java:56)
       - waiting to lock <0x000000078e5ab5a0> (a java.lang.Object)
       at com.example.MyClass.method1(MyClass.java:42)
       - locked <0x000000078e5ab5a0> (a java.lang.Object)

    输出中列出了参与死锁的线程,以及它们当前的堆栈信息。你可以根据这些信息来修复死锁问题。

  5. 分析线程堆栈信息

    生成线程堆栈后,分析堆栈信息非常重要。你需要检查每个线程的状态、调用栈,以及是否存在死锁或长时间运行的线程。以下是一些关键点:

    • 线程状态 :检查线程是否处于 WAITINGTIMED_WAITINGBLOCKEDRUNNABLE 状态。
    • 死锁:如果多个线程在互相等待对方释放锁,则可能存在死锁。
    • CPU占用高:某些线程可能在耗费大量 CPU,长时间运行在同一个方法里。
  6. 分析线程状态

    线程堆栈的状态可以有以下几种:

    • NEW: 新创建的线程,尚未开始执行。
    • RUNNABLE: 线程正在执行(包括等待 CPU 时间)。
    • BLOCKED: 线程正在等待获取一个锁。
    • WAITING: 线程在等待某个条件发生。
    • TIMED_WAITING: 线程在等待一个特定时间后会自动唤醒。
    • TERMINATED: 线程已经结束执行。

    通过分析这些状态,可以帮助诊断应用程序的性能问题。

注意事项

  • 权限问题 :你通常需要管理员权限或目标进程的用户权限才能使用 jstack 生成线程堆栈信息。
  • 生产环境使用小心:在生产环境中,生成线程堆栈会对应用程序的性能造成一定的影响,尤其是在高负载的情况下,因此使用时要小心。
  • 堆栈信息量大:线程堆栈信息可能非常庞大,分析时需要耐心。

Jstat

jstat 是 Java 提供的一个命令行工具,用于监控和分析 Java 虚拟机(JVM)的运行时统计信息。通过 jstat,你可以查看 JVM 各种性能指标,例如内存使用、垃圾回收、类加载、编译等。这对于性能调优和故障排查非常有帮助。

jstat 使用步骤

  1. 查看 JVM 进程的 PID

    在使用 jstat 之前,首先需要找出目标 JVM 进程的进程 ID(PID)。你可以通过 jps 命令来列出系统中所有的 Java 进程。

    bash 复制代码
    jps

    该命令会列出当前系统上运行的所有 Java 进程。例如:

    bash 复制代码
    12345 MyJavaApp

    这里 12345 就是 Java 应用程序的进程 ID(PID)。

  2. 查看 jstat 支持的选项

    jstat 命令有多个选项,可以用于查看不同的 JVM 统计信息。你可以通过 -help 参数来查看支持的选项和用法。

    bash 复制代码
    jstat -help

    输出将列出所有可用的选项,例如:

    • -gc:显示垃圾回收信息。
    • -gcutil:显示垃圾回收的统计信息(百分比形式)。
    • -class:显示类加载信息。
    • -compiler:显示 JIT 编译器信息。
  3. 使用 jstat 命令查看 JVM 性能指标

    下面是一些常用的 jstat 命令示例。

    • 查看垃圾回收(GC)统计信息

      -gc 选项显示垃圾回收的详细信息,常用来检查堆内存使用情况。

      bash 复制代码
      jstat -gc <PID> 1000

      其中:

      • <PID> 是目标 Java 进程的 PID。
      • 1000 是时间间隔(单位:毫秒),表示每 1000 毫秒打印一次 GC 信息。

      输出示例:

      yaml 复制代码
      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    2048.0 1500.0 8192.0 5000.0 1024.0 500.0  1024.0 500.0  5      0.215  2      0.110  0.325

      每列的含义如下:

      • S0CS1C: Survivor 区域的容量。
      • S0US1U: Survivor 区域的已使用内存。
      • ECEU: Eden 区域的容量和已使用内存。
      • OCOU: Old 区域的容量和已使用内存。
      • MCMU: Metaspace 区域的容量和已使用内存。
      • CCSCCCSU:压缩类空间的容量和已使用内存。
      • YGCYGCT:年轻代垃圾回收次数和时间。
      • FGCFGCT:老年代垃圾回收次数和时间。
      • GCT:总垃圾回收时间。
    • 查看类加载信息

      -class 选项显示类加载器的相关信息。

      bash 复制代码
      jstat -class <PID>

      输出示例:

      css 复制代码
      Loaded    Unloaded    Time
      2345      12          45.23
      • Loaded:加载的类数量。
      • Unloaded:卸载的类数量。
      • Time:类加载时间。
    • 查看 JIT 编译器信息

      -compiler 选项显示 JIT 编译器的信息,主要用来查看方法的编译情况。

      bash 复制代码
      jstat -compiler <PID>

      输出示例:

      yaml 复制代码
      2345    12    45.23
    • 查看 Java 堆内存使用情况

      -gcutil 选项显示 JVM 堆内存的使用情况,通常用于监控垃圾回收的效果。

      bash 复制代码
      jstat -gcutil <PID> 1000

      输出示例:

      S0    S1    E     O     M     CCS   YGC   YGCT   FGC   FGCT   GCT
      0.0   0.0   40.0  30.0  55.0  20.0  5     0.15   2     0.05   0.2
      

      各列代表:

      • S0S1:分别是 survivor 区的使用百分比。
      • E:Eden 区的使用百分比。
      • O:Old 区的使用百分比。
      • M:Metaspace 区的使用百分比。
      • CCS:压缩类空间的使用百分比。
      • YGCYGCT:年轻代垃圾回收次数和时间。
      • FGCFGCT:老年代垃圾回收次数和时间。
      • GCT:总垃圾回收时间。
  4. 常用选项总结

    以下是 jstat 的一些常用选项:

    • -gc:显示垃圾回收信息。
    • -gcutil:以百分比显示垃圾回收的统计信息。
    • -class:显示类加载信息。
    • -compiler:显示 JIT 编译器信息。
    • -printcompilation:显示已编译的代码。
  5. 分析 jstat 输出信息

    jstat 输出的统计数据可以帮助你了解 JVM 的内存使用情况,尤其是垃圾回收的行为。根据输出数据,你可以判断:

    • GC 是否频繁:频繁的 GC 可能表明堆内存不足或者对象创建过于频繁。
    • 内存是否有泄漏:长期不回收的内存可能是内存泄漏的征兆。
    • JIT 编译效果:查看是否有过多方法被解释执行,可能需要调整 JIT 编译策略。
  6. 注意事项

    • jstat 主要用于监控和诊断 JVM 性能,但它不提供详细的线程或堆栈信息。如果需要更深入的分析,可以结合 jstackjmap 或 VisualVM 等工具。
    • jstat 的命令可以按时间间隔持续输出,适合用于实时监控。
    • 需要确保你有足够的权限访问目标 JVM 进程(通常需要是目标进程的所有者或具有管理员权限)。

MAT

Eclipse Memory Analyzer Tool(MAT)是一个强大的工具,用于分析 Java 应用程序中的堆转储(heap dump),帮助开发者诊断内存泄漏和内存使用不当的问题。以下是使用 MAT 工具的基本步骤:

1. 下载并安装 MAT

首先,你需要下载并安装 Eclipse Memory Analyzer Tool(MAT):

  • 访问 MAT 官网 下载适用于你操作系统的版本。
  • 解压并运行 MAT。

2. 获取堆转储文件

MAT 的主要功能是分析堆转储文件。堆转储(heap dump)是 JVM 在运行过程中产生的内存快照,它包含了堆内存中所有对象的详细信息。你可以通过以下几种方式获得堆转储文件:

2.1 通过 JDK 工具生成堆转储文件

  • 使用 jmap 命令 :这是最常用的方法之一。你可以通过 jmap 命令来生成堆转储文件。

    bash 复制代码
    jmap -dump:live,format=b,file=heapdump.hprof <PID>

    其中:

    • -dump:指定堆转储的生成方式。
    • live:表示只包含活动对象。
    • format=b:表示输出文件格式为二进制格式(可以是 .hprof 格式)。
    • <PID>:目标 Java 进程的进程 ID。

    例如,生成堆转储文件 heapdump.hprof

2.2 通过 JVM 参数生成堆转储文件

你也可以在 JVM 启动时通过以下参数来设置自动生成堆转储文件:

bash 复制代码
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heapdump.hprof

这样,在发生 OutOfMemoryError 时,JVM 会自动生成堆转储文件。

3. 导入堆转储文件到 MAT

  1. 打开 MAT 工具。
  2. 选择 File -> Open Heap Dump
  3. 选择你之前生成的 .hprof 文件,并点击 Open

4. 分析堆转储文件

当堆转储文件加载完毕后,MAT 会开始分析堆转储中的内容。分析过程中,MAT 会为你提供各种视图和统计信息,帮助你识别内存问题。

4.1 初步分析

MAT 会在打开堆转储文件后自动生成一个快速概览报告。你可以在报告中查看以下信息:

  • 对象数量统计:显示堆中每种类型对象的数量和占用内存。
  • 最常用的类:列出内存中占用最多空间的类。
  • 内存泄漏提示:MAT 会尝试自动检测潜在的内存泄漏(如果某个对象占用了大量内存且没有被正确释放)。

4.2 查看对象实例

在 MAT 中,你可以查看堆中的所有对象实例。选择 Dominator Tree 视图或 Histogram 视图可以帮助你识别占用大量内存的对象。

  • Dominator Tree:显示对象之间的引用关系,能够帮助你查找大对象及其依赖的对象。
  • Histogram:显示对象类型和实例的分布,你可以按对象的实例数或占用的内存量排序。

4.3 查找内存泄漏

MAT 提供了一个强大的内存泄漏检测工具:

  • 点击 Leak Suspects Report 按钮,这将启动 MAT 的内存泄漏检查功能。MAT 会根据堆的引用图谱分析是否有无法回收的对象。
  • 分析结果将列出可能的内存泄漏源,并显示这些对象的详细信息,如大小、引用路径等。

4.4 对象路径分析

你可以使用 Path to GC Roots 功能来追踪某个对象为何没有被垃圾回收。MAT 会显示从该对象到垃圾回收根节点(GC Root)之间的引用路径,这有助于发现那些导致对象无法被回收的引用。

5. 分析常见问题

MAT 可以帮助你诊断一些常见的内存问题:

  • 内存泄漏:MAT 会显示无法回收的对象及其引用路径,帮助你找出内存泄漏的根源。
  • 高内存使用:MAT 会显示占用大量内存的对象和类,有助于你识别内存使用不当的地方。
  • 对象增长异常:通过跟踪对象实例的增长趋势,你可以发现哪些对象的增长异常,导致内存不断增加。

6. 生成报告

完成分析后,你可以生成详细的报告。MAT 支持导出为各种格式,如 HTML、XML 等。可以通过 File -> Export 来导出分析结果。

7. 优化建议

根据 MAT 分析结果,你可能会发现以下几类问题:

  • 不可达对象:这些对象已经没有活跃的引用,但依然占用内存。
  • 过大的单一对象:某些单个对象的内存占用可能过高,建议优化其存储结构或拆分成更小的对象。
  • 不必要的引用:某些对象的引用可能不必要,导致它们无法被垃圾回收。

通过这些信息,你可以着手优化代码,消除内存泄漏和过度内存使用的情况。

8. 常见的分析视图

  • Dominator Tree:按内存占用的对象层次结构展示堆中的对象,可以识别哪些对象是内存的"支配者"。
  • Histogram:显示堆中所有对象的统计信息,按类、大小等排序。
  • Leak Suspects Report:自动生成的内存泄漏分析报告。
  • Path to GC Roots:帮助分析某个对象为何无法被垃圾回收。

Jconsole

JConsole 是 JDK 自带的一个用于监视和管理 Java 应用程序的图形化工具。它可以实时显示 JVM 的运行状况,包括内存使用、线程活动、垃圾回收、类加载等信息,适合开发者进行性能监控和故障诊断。以下是使用 JConsole 的基本步骤:

1. 启动 JConsole

1.1 在命令行启动

  • 确保 JDK 已安装,并将 JDK 的 bin 目录加入到系统的环境变量 PATH 中。

  • 打开命令行终端,输入以下命令启动 JConsole:

    bash 复制代码
    jconsole

    这会打开 JConsole 图形界面。

1.2 通过 Java 应用程序启动

你也可以通过直接启动 Java 应用程序时开启远程监控来启动 JConsole。

  • 例如,在启动 Java 应用时加上 JVM 参数:

    bash 复制代码
    java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=12345 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -jar your-application.jar

    这将启用 JMX 远程监控,并使得你能够通过 JConsole 连接到正在运行的应用程序。

2. 连接到 Java 应用

启动 JConsole 后,它会列出当前所有正在运行的 Java 进程。你可以选择以下方式连接到你想监控的 Java 应用程序:

2.1 本地连接

如果你是在本地机器上运行 Java 程序,JConsole 会自动列出当前所有的 Java 进程。你只需选择你要连接的进程并点击 Connect 即可。

2.2 远程连接

如果你想连接到远程的 Java 应用程序,选择 Remote Process 选项,并输入远程应用程序的主机名和端口号(例如:hostname:12345)。确保目标应用程序已经启用 JMX 远程连接。

3. 使用 JConsole 监控应用程序

成功连接后,JConsole 会显示多个监控标签页,分别用于展示不同的系统和应用状态信息。以下是一些主要的功能标签:

3.1 Overview(概览)

  • CPU 使用情况:显示 JVM 进程的 CPU 使用率。
  • 内存使用情况:显示 JVM 堆内存的使用情况,包括年轻代、老年代和永久代(如果有的话)的内存使用。
  • 线程活动:显示当前活动线程数以及线程状态的分布。

3.2 Memory(内存)

该标签页提供堆内存的详细信息,包括:

  • 堆内存:显示当前堆的使用情况,按年轻代、老年代、持久代划分。
  • 内存池:显示不同内存池(如 Eden 区、Survivor 区、Old 区)的内存使用情况。
  • 垃圾回收:显示垃圾回收的次数和时间。

在这里,你还可以手动触发垃圾回收(点击 Perform GC 按钮)。

3.3 Threads(线程)

该标签页显示 JVM 中的线程活动,包括:

  • 线程概览:显示当前线程的总数和线程状态(如运行中、阻塞中、等待中等)。
  • 线程堆栈:你可以查看每个线程的堆栈跟踪,帮助你诊断死锁等线程问题。

3.4 Classes(类)

显示 JVM 中加载的类的统计信息,包括:

  • 加载的类数:显示当前加载的类数量。
  • 加载/卸载类:显示加载和卸载类的数量,帮助你检测是否有类加载异常。

3.5 VM (虚拟机)

该标签提供 JVM 进程的状态和配置,包括:

  • JVM 参数:显示当前 JVM 启动时使用的参数。
  • 系统属性:显示系统属性列表。

3.6 MBeans(MBeans)

在这个标签页中,你可以查看和操作应用程序暴露的 JMX MBeans。MBeans 是 Java 管理扩展 (JMX) 中用于管理应用程序、设备、系统或网络服务的组件。如果你有自定义的 MBeans(例如应用程序监控数据),可以在这里进行交互。

4. 性能优化和问题诊断

使用 JConsole 监控时,开发者可以发现以下性能瓶颈并进行优化:

  • 内存泄漏 :如果堆内存使用不断上升,而垃圾回收没有有效清除对象,可能是内存泄漏的征兆。你可以通过 Memory 视图中的堆内存使用情况进行检查。

  • 高 CPU 使用率 :通过 Overview 标签中的 CPU 使用图表,检查应用程序是否出现异常的 CPU 消耗,进而优化相关的代码或调整 JVM 参数。

  • 线程问题 :通过 Threads 视图,你可以查看线程的活跃度,检查是否存在线程阻塞、死锁等问题。

  • 垃圾回收瓶颈 :通过 Memory 标签,你可以监控垃圾回收的频率和时间,过长的垃圾回收时间可能是性能瓶颈的标志,可以考虑调优堆大小或使用其他垃圾回收器(如 G1 GC)。

5. 警告和告警

JConsole 本身并不提供告警功能,但是可以通过监控 JVM 的各种性能指标并结合日志分析来触发告警。例如,当垃圾回收频繁且停顿时间过长时,你可以通过配置合适的告警系统来响应这些问题。

总结

JConsole 是一个轻量级且功能丰富的监控工具,适用于开发者实时监控 Java 应用的运行状态。通过 JConsole,可以直观地看到 Java 应用的内存使用、线程状态、垃圾回收等关键指标,及时发现和解决性能问题。

VisualVM

VisualVM 是一个功能强大的 Java 虚拟机(JVM)监控、性能分析和故障排查工具,允许开发者实时查看 JVM 的运行情况,进行性能分析、内存分析、线程分析等。VisualVM 是 JDK 自带的工具,可以帮助开发者在运行时获取 Java 程序的详细信息,从而进行优化和问题诊断。

以下是 VisualVM 使用的步骤:

1. 安装 VisualVM

  • VisualVM 在 JDK 8 及以上版本中已经作为 JDK 工具之一预装。你可以直接在 JDK 的 bin 目录中找到 jvisualvm 可执行文件。
  • 如果你使用的是较旧的 JDK 或者想安装 VisualVM 最新版本,可以访问 VisualVM 官网 下载并安装。

2. 启动 VisualVM

2.1 从命令行启动

  • 在命令行中直接输入 jvisualvm,如果已经安装并配置好 JDK 环境变量,VisualVM 会自动启动。

2.2 从 JDK bin 目录启动

  • 如果 jvisualvm 没有配置在 PATH 环境变量中,可以直接在 JDK 的 bin 目录下找到并运行 jvisualvm

2.3 启动后的界面

  • 启动 VisualVM 后,你会看到一个包含多个选项卡的界面,主要包括:
    • Applications:列出当前运行的本地和远程 Java 应用程序。
    • ProfilerMonitorHeap Dump 等标签,用于查看和分析 Java 应用的各类性能指标。

3. 连接到 Java 应用程序

VisualVM 支持连接本地和远程的 Java 应用程序,具体方式如下:

3.1 本地连接

  • 启动 VisualVM 后,Applications 标签页下会自动显示本地机器上所有正在运行的 Java 进程。
  • 选择你要监控的进程,双击即可连接。

3.2 远程连接

  • 如果你希望监控远程机器上的 Java 应用程序,需要在远程 JVM 中启用 JMX 远程连接:
    • 在启动 Java 应用时,使用以下 JVM 参数来启用远程监控:

      bash 复制代码
      java -Dcom.sun.management.jmxremote \
           -Dcom.sun.management.jmxremote.port=12345 \
           -Dcom.sun.management.jmxremote.ssl=false \
           -Dcom.sun.management.jmxremote.authenticate=false \
           -jar your-application.jar
    • 然后,在 VisualVM 中,右键点击 Applications 标签页的空白区域,选择 Add Remote Host

    • 输入远程主机的 IP 地址,并添加远程 JVM 连接信息(如 hostname:port),连接后可以查看远程应用程序的性能信息。

4. 使用 VisualVM 监控应用程序

4.1 Monitor(监控)

  • Monitor 标签页展示了应用程序的实时运行状态,包括:
    • CPU 使用情况:展示应用程序的 CPU 占用情况。
    • 内存使用情况:显示应用程序堆内存和非堆内存的使用情况。
    • 垃圾回收:显示垃圾回收的情况和时间。
    • 线程活动:显示线程的活动状态,帮助你查看线程的使用情况。

4.2 Profiler(性能分析)

  • Profiler 标签页提供详细的性能分析,包括:
    • CPU 性能分析:通过采样方式,查看哪些方法在 CPU 上消耗最多的时间。
    • 内存性能分析:查看对象分配和内存使用的情况,帮助检测内存泄漏。
    • 方法调用图:展示哪些方法最耗时,或者哪个方法被调用最多。

4.3 Heap Dump(堆转储)

  • Heap Dump 允许你生成堆转储文件,并分析对象的内存占用情况。它可以帮助你发现内存泄漏,查看哪些对象占用的内存较多。
    • Heap Dump 标签页中,可以通过点击 Heap Dump 按钮生成堆转储。
    • 在生成堆转储后,VisualVM 会展示堆中各个对象的详细信息,包括类名、实例数和内存占用等。

4.4 Thread Dump(线程转储)

  • Thread Dump 用于查看当前 JVM 中所有线程的状态,以及线程的堆栈信息。
    • Threads 标签页中,你可以查看当前线程的状态(如运行中、等待中、阻塞中等),以及线程的堆栈信息。
    • 通过 Thread Dump,你可以帮助诊断死锁、线程阻塞等问题。

4.5 VM Options(虚拟机选项)

  • VM Options 中,可以查看和修改 JVM 启动时的参数配置。
  • 如果你发现某些性能问题,需要调优 JVM 参数,可以通过这个界面直接调整。

5. 诊断和性能优化

5.1 内存泄漏检测

通过 ProfilerHeap Dump,你可以检测内存泄漏。内存泄漏通常表现为堆内存使用持续上升,且垃圾回收无法释放内存。你可以通过以下方式诊断:

  • Profiler 中查看对象的分配情况,查找是否有大量对象未被回收。
  • Heap Dump 中查看哪些对象占用了大量内存,确定可能的内存泄漏源。

5.2 CPU 使用分析

通过 Profiler 中的 CPU Sampling,你可以查看哪些方法消耗了过多的 CPU 时间,进而进行性能优化。

  • 分析耗时方法,查看代码中是否存在性能瓶颈。
  • 优化算法或逻辑,减少 CPU 占用。

5.3 线程分析

通过 ThreadsThread Dump,你可以诊断线程的问题,例如死锁、线程饥饿等。

  • 检查线程的状态,看看是否存在大量阻塞或等待的线程。
  • 使用 Thread Dump 分析线程堆栈,查看是否有死锁发生。

6. 生成报告

VisualVM 提供了将分析结果导出为报告的功能。你可以导出 Heap DumpThread Dump ,并生成 性能分析报告。这些报告可以帮助你保存诊断结果,并与团队成员分享。

总结

VisualVM 是一个非常强大的 Java 性能监控和故障诊断工具,具有实时监控、性能分析、内存分析、线程分析等功能。通过使用 VisualVM,开发者能够及时发现性能瓶颈,优化应用程序,解决内存泄漏、死锁等问题,从而提升 Java 应用程序的稳定性和性能。

Arthus

Arthas 是一个开源的 Java 诊断工具,专为 Java 程序提供动态诊断功能,能够在不修改代码的情况下实时诊断、分析和优化应用程序。它支持查看堆栈、调试线程、监控 JMX 等功能,非常适用于生产环境中的问题排查。

以下是 Arthas 的基本使用步骤:

1. 安装和准备

Arthas 是通过命令行工具运行的,可以通过以下几种方式安装和启动:

1.1 使用 JAR 包 直接运行

  1. Arthas GitHub官方网站 下载最新版本的 Arthas JAR 包。

  2. 使用以下命令启动 Arthas:

    bash 复制代码
    java -jar arthas-boot.jar

    运行后,Arthas 会尝试连接到当前机器上所有的 Java 进程。

1.2 使用 Homebrew 安装(macOS/Linux)

  • 在 macOS 或 Linux 系统上,你可以通过 Homebrew 安装 Arthas:

    bash 复制代码
    brew install arthas

1.3 使用 Docker 启动

如果你使用 Docker,可以直接通过 Docker 启动 Arthas:

bash 复制代码
docker run -it --rm -v /tmp:/tmp --pid=host  aliyun/arthas

2. 连接到 Java 进程

启动 Arthas 后,它会列出当前运行在本地的所有 Java 进程。你需要选择你想要调试或诊断的进程。

  • 输入相应的进程 ID(PID),然后按回车连接该进程。

3. 常用命令

Arthas 提供了丰富的命令行工具,以下是一些常用的命令:

3.1 monitor --- 方法监控

monitor 用于监控某个方法的调用次数、耗时等信息。比如,监控 com.example.MyClass 类的 myMethod 方法:

bash 复制代码
monitor com.example.MyClass myMethod

可以增加 -n 参数指定显示多少次调用统计,-d 参数指定显示方法耗时等信息。

3.2 jad --- 反编译

jad 用于反编译类的字节码,查看该类的源码。比如反编译 com.example.MyClass

bash 复制代码
jad com.example.MyClass

反编译后,Arthas 会显示该类的 Java 源代码。

3.3 stack --- 查看线程栈

stack 命令用来查看当前 JVM 中所有线程的堆栈信息,非常适合排查死锁、线程阻塞等问题。默认查看所有线程的堆栈信息,输入以下命令:

bash 复制代码
stack

可以使用 -t 参数查看特定线程的堆栈:

bash 复制代码
stack -t <thread-name>

3.4 thread --- 线程监控

thread 命令提供线程状态的实时监控,可以查看线程池中的线程数量、线程状态等信息:

bash 复制代码
thread

3.5 watch --- 监视方法调用

watch 可以在不修改代码的情况下动态地插桩某个方法,并打印方法执行的入参、返回值或执行时间等。例如,监控 com.example.MyClass 中的 myMethod 方法,并打印入参和返回值:

bash 复制代码
watch com.example.MyClass myMethod '{params,returnObj}'

如果你只想监控方法的执行时间,可以使用如下命令:

bash 复制代码
watch com.example.MyClass myMethod -t

3.6 trace --- 方法调用追踪

trace 可以用来追踪某个方法的执行情况,包括方法的调用栈、耗时等。比如:

bash 复制代码
trace com.example.MyClass myMethod

3.7 cls --- 清除命令

当命令行输出太多时,你可以使用 cls 来清除屏幕内容,保持终端干净:

bash 复制代码
cls

3.8 exit --- 退出 Arthas

如果你完成了对进程的诊断,可以通过 exit 命令退出 Arthas:

bash 复制代码
exit

4. 调试和分析

4.1 查看 JVM 信息

可以使用 jvm 命令查看 JVM 的相关信息,包括堆内存、非堆内存、线程数、垃圾回收等:

bash 复制代码
jvm

4.2 查看类加载器信息

可以使用 classloader 命令查看当前 JVM 的类加载器信息:

bash 复制代码
classloader

4.3 动态修改类

Arthas 还可以动态修改类,热更新方法体(使用 bytecode 命令)。例如,修改某个类的字节码:

bash 复制代码
bytecode com.example.MyClass

然后选择操作,如修改、替换等。可以直接在生产环境进行调试,不需要重启应用。

5. 高级功能

Arthas 支持一些更高级的功能,比如:

5.1 heapdump --- 堆转储

通过 heapdump 命令,你可以生成堆转储文件并分析内存使用情况。该命令会生成一个堆转储文件并保存到指定位置:

bash 复制代码
heapdump

5.2 sc --- 查看 Spring Bean

如果你的应用是基于 Spring 的,可以使用 sc 命令来查看 Spring 上下文中的 Bean 信息。比如查看某个 Bean:

bash 复制代码
sc com.example.MyService

5.3 watchtrace 的条件断点

watchtrace 命令支持设置条件断点(如方法执行时间超过一定阈值时触发)。例如,在 myMethod 方法上设置一个执行时间超过 100ms 时触发的 watch 命令:

bash 复制代码
watch com.example.MyClass myMethod 'returnObj' -n 10 -t -x 100

6. 导出诊断数据

如果需要将 Arthas 的诊断结果保存为文件或共享给团队成员,可以使用 log 命令导出日志:

bash 复制代码
log /tmp/arthas.log

7. 退出 Arthas

完成诊断后,使用 exit 命令退出 Arthas:

bash 复制代码
exit
相关推荐
hummhumm1 小时前
第 10 章 - Go语言字符串操作
java·后端·python·sql·算法·golang·database
man20173 小时前
【2024最新】基于springboot+vue的闲一品交易平台lw+ppt
vue.js·spring boot·后端
hlsd#3 小时前
关于 SpringBoot 时间处理的总结
java·spring boot·后端
路在脚下@3 小时前
Spring Boot 的核心原理和工作机制
java·spring boot·后端
幸运小圣3 小时前
Vue3 -- 项目配置之stylelint【企业级项目配置保姆级教程3】
开发语言·后端·rust
前端SkyRain4 小时前
后端Node学习项目-用户管理-增删改查
后端·学习·node.js
提笔惊蚂蚁4 小时前
结构化(经典)软件开发方法: 需求分析阶段+设计阶段
后端·学习·需求分析
老猿讲编程5 小时前
Rust编写的贪吃蛇小游戏源代码解读
开发语言·后端·rust
黄小耶@5 小时前
python如何使用Rabbitmq
分布式·后端·python·rabbitmq
宅小海6 小时前
Scala-List列表
开发语言·后端·scala