参考:

JVMTI 应用场景

  1. class 文件加密

    • 使用一些常规的手段
      (例如使用混淆器或者自定义类加载器)来对class文件进行加密很容易被反编译。反编译后的代码虽然增加了阅读的难度,但花费一些功夫也是可以读懂的。
    • 使用 JVMTI
      我们可以将解密的代码封装成 .dll.so 文件。
      这些文件想要反编译就很麻烦了,另外还能加壳。
  2. 性能监控 (application performance management,APM)、诊断(profile)

    1. 基于JVMTI的APM能够解决分布式架构和微服务带来的监控和运维上的挑战。
      开源的Pinpoint, ZipKin, Hawkular,商业的AppDynamics,OneAPM,Google Dapper等都是个中好手。
    2. 能对 cpu使用率过高、线程死锁等问题进行诊断
      例如Alibaba开源的Java诊断工具Arthas
      它可以查看或者动态修改某个变量的值、统计某个方法调用链上的耗时、拦截方法前后,打印参数值和返回值,以及异常信息等
  3. <mark>JAVA程序的调试(debug)</mark> 【开发者来说,最实用!】

    这是 开发工具 调试的原理
    <mark>如 eclipse 的调试器org.eclipse.jdt.debug插件底层就是调用的JVMTI来实现的</mark>。
    同时对于分布式、微服务提供了 <mark>远程调试</mark> 的可能!
    google甚至推出了云端调试工具cloud debugger。
    它使一个web应用,可以直接对生产环境进行<mark>远程调试</mark>,不需要重启或者中断服务。
    阿里也有类似的工具Zdebugger。

  4. 热加载

    热部署的原理

JVMTI - JVM 工具接口

Java虚拟机 <mark>工具接口</mark>(JVMTI,JVM Tool Interface)

形象地说
JVMTI是Java虚拟机提供的一整套 <mark>后门</mark>。
通过这套后门可以对虚拟机方方面面进行 <mark>监控,分析</mark>。
甚至 <mark>干预虚拟机的运行</mark>。

前身是

  • 虚拟机调试接口(Java Virtual Machine Debug Interface,JVMDI)
  • 虚拟机性能调节接口(Java Virtual Machine Profiler Interface,JVMPI)

在 J2SE 5.0 (2005年)之后 JDK 取代了JVMDI 和 JVMPI 这两套接口

JVMDI 在最新的 Java SE 6 中已经不提供支持,而 JVMPI 也计划在 Java SE 7 后被彻底取代。

JPDA - JAVA平台调试架构

继续了解之前,需要先了解下 <mark>Java平台调试体系(Java Platform Debugger Architecture,JPDA)</mark>。

JPDA被抽象为三层实现

  • 其中 JVMTI 就是JVM 对外暴露的接口
  • JDI 是实现了JDWP 通信协议的客户端
  • 调试器 它通过JDI和JVM中被调试程序通信。

JVMTI 的本质

<mark>JVMTI 本质上是在JVM内部的许多事件进行了埋点</mark>。通过这些埋点可以给外部提供当前上下文的一些信息。甚至可以接受外部的命令来改变下一步的动作。

  • 外部程序一般利用C/C++实现一个 JVMTIAgent ,在Agent里面注册一些 JVM事件的回调
  • 当事件发生时JVMTI调用这些 回调方法
  • Agent可以在回调方法里面实现 自己的逻辑
    其中,<mark>JVMTIAgent是以 动态链接库 的形式被虚拟机加载的</mark>。

JVMTI 的地位

JVMTI处于整个JPDA 体系的最底层,<mark>所有调试功能本质上都需要通过 JVMTI 来提供</mark>。

  • 从大的方面来说
    JVMTI 提供了可用于 debug 和profiler 的接口;
    同时,在 Java 5/6 中,虚拟机接口也增加了监听(Monitoring),线程分析(Thread analysis)以及覆盖率分析(Coverage Analysis)等功能。

  • 从小的方面来说
    包含了虚拟机中线程、内存、堆、栈、类、方法、变量,事件、定时器处理等等诸多功能。

具体可以参考oracle 的文档:
《JVMTM Tool Interface》https://docs.oracle.com/javase/1.5.0/docs/guide/jvmti/jvmti.html

通过这些接口,开发人员不仅可以调试在该虚拟机上运行的 Java 程序,还能查看它们运行的状态,设置回调函数,控制某些环境变量,从而优化程序性能。

JVMTI 的实现

JVMTI 并不一定在所有的 Java 虚拟机上都有实现,不同的虚拟机的实现也不尽相同。不过在一些主流的虚拟机中,比如 Sun 和 IBM,以及一些开源的如Apache Harmony DRLVM 中,都提供了标准 JVMTI 实现。