「JVM 故障诊断」可视化工具(WIP)

1. JHSDB

基于服务性代理(HotSpot VM 中一组用于映射 Java VM 运行信息的 API 集合,可以通过独立的 Java VM 进程分析其他 HotSpot VM 的内部数据)的进程外调试工具,类似 JCMD 的多功能工具箱;

  1. JHSDB vs. JCMD
基础工具JCMDJHSDB
jps -lmjcmdN/A
jmap -dump pidjcmd pid GC.heap_dumpjhsdb jmap --binaryheap
map -histo pidjcmd pid GC.class_histogramjhsdb jmap --histo
jstack pidjcmd pid Thread.printjhsdb jstack --locks
jinfo -sysprops pidjcmd pid VM.system_propertiesjhsdb info --sysprops
jinfo -flags pidjcmd pid VM.flagsjhsdb jinfo --flags
  1. 通过 JHSDB 查看变量本身位置

VM Arguments 设置

# 限制 Java Heap 大小,加快在内存中搜索对象
# 禁用压缩指针(JHSDB 对压缩指针的支持存在缺陷)
-Xmx10m -XX:+UseSerialGC -XX:-UseCompressedOops

示例代码

static class ObjectHolder {
}

static class Test {
    // 随类信息存放在方法区
    static ObjectHolder staticObj = new ObjectHolder();
    // 随对象存放在 Java Heap
    ObjectHolder instanceObj = new ObjectHolder();

    void foo() {
        // 存放在 foo() 方法栈帧的局部变量表
        ObjectHolder localObj = new ObjectHolder();
        System.out.println("done.");
    }
}

public static void main(String[] args) {
    Test test = new JHSDBTest.Test();
    test.foo();
}

JHSDB 使用

# 找到要分析的程序的进程号
jps -l

# 进入 JHSDB 图形化界面,附加进程 20
jhsdb hsdb --pid 20
  • Tools -> Heap Parameters: 查看内存布局;
  • Windows -> Console: 可以通过 scanoops 命令查找 Java Heap 中的对象实例,eg: hsdb>scanoops 0x00007f32c7800000 0x00007f32c7b50000 JHSDB_TestCase$ObjectHolder
  • Tools -> Inspector: 通过地址查找对象本身,展示对象头和对象元数据(Java 类型名称、继承关系、实现接口关系、字段信息、方法信息、运行时常量池的指针、内嵌的虚方法表、接口方法表等);
  • Stack Memory: 查看现场的栈内存;

2. JConsole(Java Monitoring and Management Console)

基于 JMX(Java Management Extensions)的可视化监视、管理工具;通过 JMX 的 MBean(Managed Bean)对系统进行信息收集和参数动态调整;

  • 概述,堆内存使用情况、线程、类、CPU 使用情况的概览;
  • 内存,相当于可视化的 jstat,堆 Java Heap 的状态和 GC 信息做持续采集展示;
  • 线程,相当于可视化的 jstack,分析线程停顿问题(外部资源等待、死循环、锁等);
  • ,Loaded Class 统计信息;
  • VM 摘要,JVM 进程配置与环境等摘要信息;
  • MBean,实现了 JMX 接口的 Managed Bean 对象;

3. VisualVM

All-in-One Java Troubleshooting Tool,功能最强大的运行监视和故障处理工具之一,比值专业收费的 Profiling 工具(JProfiler、YourKit)也不遑多让;不需要基于特殊 Agent,且对应用程序性能影响较小,可在生产环境直接使用;

  1. 配置 VisualVM 的 JAVA_HOME
# 在 VisualVM/Contents/Resources/etc/visualvm.conf 追加 jdk home
visualvm_jdkhome="/Users/cm.huang/Documents/devutils/jdk8u345-b01//Contents/Home"
  1. VisualVM 功能(配合插件)
  • 显示 JVM 进程及配置、环境信息(jps、jinfo -> Overview);
  • 监视 JVM 进程的 CPU、GC、Heap、Method Area、Thread 等信息(jstat、jstack -> Monitor);
  • 生成和分析 Heap、Thread 转储快照(jmap、jhat、jstack -> Monitor、Threads);
  • 跟踪方法级运行性能,分析调用最多、耗时最久的方法(Profiler);
  1. BTrace 动态日志跟踪

BTrace,基于 Java 虚拟机的 Instrument 开发的,可实现动态修改目标程序的工具;可用于打印堆栈、参数、返回值等,进而进行性能监视、定位连接泄漏、内存泄漏、分析多线程竞争问题等;

代码示例

// 目标程序代码
public class BTraceTest {
    public int add(int a, int b) {
        return a + b;
    }

    public static void main(String[] args) throws IOException {
        BTraceTest test = new BTraceTest();
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        for (int i = 0; i < 10; i++) {
            reader.readLine();
            int a = (int) Math.round(Math.random() * 1000);
            int b = (int) Math.round(Math.random() * 1000);
            System.out.println(test.add(a, b));
        }
    }
}
// BTrace 织入的代码
/* BTrace Script Template */
import org.openjdk.btrace.core.annotations.*;
import static org.openjdk.btrace.core.BTraceUtils.*;

@BTrace
public class TracingScript {
    @OnMethod(clazz = "edu.aurelius.jvm.util.BTraceTest", method = "add", location = @Location(Kind.RETURN))
    public static void func(@Self edu.aurelius.jvm.util.BTraceTest instance, int a, int b, @Return int result) {
        println("调用堆栈:");
        jstack();
        println(strcat("方法参数A:", str(a)));
        println(strcat("方法参数B:", str(b)));
        println(strcat("方法结果:", str(result)));
    }
}

运行结果

在 BTrace 织入上文代码,点击 Start,然后在目标程序控制台输入回车触发程序循环执行,观察 BTrace 的 Output 面板输出;

* Starting BTrace task
** Compiling the BTrace script ...
*** Compiled
** Instrumenting 1 classes ...
*** Done
** BTrace up&running

*** Done
** BTrace up&running

调用堆栈:
edu.aurelius.jvm.util.BTraceTest.add(BTraceTest.java:13)
edu.aurelius.jvm.util.BTraceTest.main(BTraceTest.java:23)
方法参数A:969
方法参数B:328
方法结果:1297
调用堆栈:
edu.aurelius.jvm.util.BTraceTest.add(BTraceTest.java:13)
edu.aurelius.jvm.util.BTraceTest.main(BTraceTest.java:23)
方法参数A:528
方法参数B:802

4. JMC(Java Mission Control)

JFR(Java Flight Recorder,对生产环境影响很低的 JVM 内建监控和信息收集框架,对目标应用完全透明)飞行记录仪用于持续收集数据,JMC 用于监控 JVM 的 MBean,作为 JMX 的控制台,也作为 JFR 的分析工具;

VM Arguments 设置

-Dcom.sun.management.jmxremote.port=9999 # jmx 服务端口
-Dcom.sun.management.jmxremote.ssl=false # 启用 ssl 连接
-Dcom.sun.management.jmxremote.authenticate=false # 启用授权校验
-Djava.rmi.server.hostname=localhost # jmx 服务主机名
-XX:+UnlockCommercialFeatures # 启用商业特性
-XX:+FlightRecorder # 启用 JFR

飞行记录器信息

  • 一般信息,JVM、操作系统相关信息;
  • 内存,Memory 和 GC 相关信息;
  • 代码,Mehtod、Exception、Compiler、Class Loader 等信息;
  • 线程,Threads、Lock 等;
  • I/O,File、Socket 等的 Input/Output 信息;
  • 系统,JVM 的运行环境(系统、进程、环境变量等);
  • 事件,事件类型的信息;

JFR 提供的数据往往比其他工具通过代理或 MBean 获取的质量要高得多;

  • GC,分代大小、GC 次数、时间、占用率等;
  • 内存,一段时间分配了哪些对象、哪些在 TLAB 分配、分配速率、压力大小、分配的线程、GC 对象分代晋升情况等;

5. MAT(Memory Analyzer Tool)(WIP)

6. JProfiler(WIP)

7. Arthas(WIP)

# download
curl -O https://arthas.aliyun.com/arthas-boot.jar
# attach
java -jar arthas-boot.jar <pid>

8. Frame Graphs(WIP)


上一篇:「JVM 故障诊断」命令行工具
下一篇:「JVM 故障诊断」HotSpot VM 插件与工具

PS:感谢每一位志同道合者的阅读,欢迎关注、评论、赞!


参考资料:

  • [1]《深入理解 Java 虚拟机》
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aurelius-Shu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值