Java千百问_08JDK详解(013)_JVMTI是什么

点击进入_更多_Java千百问

1、JVMTI是什么

JVMTI(JVM Tool Interface)是JPDA体系中的最底层, 由Java虚拟机提供的native编程接口,是JVMPI(Java Virtual Machine Profiler Interface)和 JVMDI(Java Virtual Machine Debug Interface)的更新版本。

了解JPDA体系看这里:JPDA是什么

从它的发展中我们就可以知道,JVMTI提供了调试(debug)和分析(profiler)功能;同时,它还有监听(Monitoring),线程分析(Thread analysis)以及覆盖率分析(Coverage Analysis)等功能。正是由于JVMTI的强大功能,它是实现Java调试器,以及其它Java运行态测试与分析工具的基础。目前已有很多成熟的集成工具提供了JVMTI的实现(例如Sun、IBM以及一些开源项目如Apache Harmony DRLVM),这些工具虽然强大易用,但是在一些特定情况下,开发者常常会有一些特殊的需求,这个时候就需要定制工具来达成目标。

JVMTI是一套本地代码接口,因此我们需要使用C/C++以及JNI。开发时一般采用建立一个Agent(通过C++编写)的方式来使用JVMTI,它可以使用JVMTI函数、设置回调函数、从JVM中得到当前的运行态信息,还可以操作虚拟机的运行态。

2、如何加载JVMTI agent

当我们把Agent编译成一个动态链接库之后,我们可以通过两种方式加载Agent:启动加载模式、活动加载模式。具体如下:

启动加载模式

在Java程序启动时加载它,其实是在java启动时指定加载agent,如下:

-agentlib:<agent-lib-name>=<options>

注意,这里的路径是环境变量的相对路径,例如 java -agentlib:libagent=opt,java启动时会PATH环境变量定义的路径处装载libagent.so

-agentpath:<path-to-agent>=<options>

这里是绝对路径,例如 java -agentpath:/home/admin/agentlib/libagent.so=opt

活动加载模式

Java 5之后可以在运行时加载agent,通过com.sun.tools.attach包的API来实现(需要引入${JAVA_HOME}/lib/tools.jar)。使用非常简单,如下:

public class TestAgent {
    public static void main(String[] args) throws AttachNotSupportedException, IOException, AgentLoadException,
            AgentInitializationException {
        String pid = "831"; // 想要装载的java进程id
        String agentPath = "/Users/sunjie/Desktop/libagent.so"; // agent.so的路径
        String options = null;// 传入agent的参数
        VirtualMachine virtualMachine = com.sun.tools.attach.VirtualMachine.attach(pid);
        virtualMachine.loadAgentPath(agentPath, options);
        virtualMachine.detach();
    }
}

了解AttachAPI看这里:[AttachAPI是什么][3]

3、JVMTI agent是如何工作的

Agent的启动

Agent是在Java虚拟机启动时加载的,这个时间点上:

  • 所有的Java类都未被初始化
  • 所有的对象实例都未被创建
  • 所有的Java代码都没有被执行

但在这个时候,我们已经可以:

  • 操作JVMTI的Capability参数
  • 使用系统参数

通过启动加载模式加载Agent之后,虚拟机会先寻找一个Agent入口函数:

JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved)

如果是运行加载模式,则是:

JNIEXPORT jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved);

在这个函数中,虚拟机传入了一个JavaVM指针,以及命令行的参数。我们通过*jvm可以获取jvmtiEnv,即可以使用JVMTI函数,当然不同的JVM实现提供的函数细节可能不一样,但是使用的方式一致。如下:

jvmtiEnv *jvmti;
(*jvm)->GetEnv(jvm, &jvmti, JVMTI_VERSION_1_1);

这里第二个参数为版本信息,不同的JVMTI环境所提供的功能、处理方式可能有所不同,不过它在同一个虚拟机中会保持不变。

Agent的卸载

当Agent完成任务,或者JVM关闭的时候,虚拟机会调用函数来完成最后的清理任务,如下:

JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *jvm)

4、如何编写JVMTI agent程序

只要有一定的C++基础就可以编写JVMTI agent,具体看这里:[如何编写JVMTI agent程序][4]

时间: 2025-01-01 21:26:26

Java千百问_08JDK详解(013)_JVMTI是什么的相关文章

Java千百问_08JDK详解(017)_Javadoc是什么

点击进入_更多_Java千百问 1.Javadoc是什么 javadoc是Sun公司提供的一个技术,它从程序源代码中抽取类.方法.成员等注释,形成一个和源代码配套的API帮助文档.也就是说,只要在编写程序时以一套特定的标签作注释,在程序编写完成后,通过Javadoc就可以形成开发文档了. 了解注释看这里:注释是什么 2.如何使用Javadoc java为javadoc技术独立出了一个工具,它位于JAVA_HOME/bin/路径中,在终端中执行如下命令: javadoc 文件名.java java

Java千百问_08JDK详解(016)_AttachAPI是什么

点击进入_更多_Java千百问 1.AttachAPI是什么 Attach API是Sun公司提供的一套扩展API,它并不是Java的标准API.顾名思义,Attach,为JVM附加某些程序.简单来说,就是把一个程序连接到一个正在运行的JVM上,连接之后,这段程序就可以在JVM中运行.这段程序被称为JVMTI Agent程序. 我们使用它可以很方便地在运行过程中动态地设置加载代理类(JVMTI Agent),使我们能方便的监控一个JVM,运行一个外加的代理程序. 了解JVMTI Agent看这里

Java千百问_08JDK详解(011)_jnlp文件是什么

点击进入_更多_Java千百问 1.jnlp文件是什么 JNLP(Java Network Launching Protocol ,java网络执行协议文件)是java提供的一种可以通过浏览器直接执行java应用程序的途径,它使你可以直接通过一个网页上的url链接打开一个java应用程序. Java桌面应用程序可以通过JNLP的方式发布.如果版本升级后,不需要再向所有用户发布版本,只需要更新服务器的版本,这就相当于让java应用程序有了web应用的优点.如果你使用JNLP打包一个应用程序,那么它

Java千百问_08JDK详解(010)_java、javaw、javaws有什么区别

点击进入_更多_Java千百问 1.java.javaw.javaws有什么区别 java.javaw.javaws这三个都是jdk自带的三个工具,都在jdk/bin路径下,这三个工具都是为了启动java应用存在的,具体区别如下: java java命令即java应用的执行器,通过它执行的应用日志会再控制台console显示输出与错误信息. 了解更多java命令看这里:java程序如何运行 javaw javaw与java一样,是java应用的执行器,不同的是它不会再控制台console显示输出

Java千百问_08JDK详解(003)_java核心框架是什么样的

点击进入_更多_Java千百问 1.jdk基础扩展类库都有什么 了解java核心框架看这里:java核心框架是什么样的 jdk基础类库分为两大部分,基础库.扩展基础库,提供了相当大量的功能,扩展基础库具体如下: I/O工具(I/O) java.io和java.nio包提供了一组非常丰富的api来管理应用程序的I/O(输入/输出).包括文件和设备I/O.对象序列化.缓冲区管理.字符集支持等.此外,API还为服务端提供了包括多路复用.非阻塞I/O.内存映射和文件锁等功能. 了解更多java.io和j

Java千百问_08JDK详解(018)_JConsole是什么

点击进入_更多_Java千百问 1.JConsole是什么 JConsole是一个Java程序性能分析器,可以从命令行或在终端中运行.可以用来监控Java程序的性能以及跟踪代码. 同时在com.sun.tools.jconsole包中提供了一组接口,允许访问JConsole,对线程.内存.类.对象进行分析和统计. 2.如何使用JConsole工具 我们这里主要介绍jconsole工具的用法,在JAVA_HOME/bin路径中,我们可以直接打开他.如下图: 我们可以对正在运行的本地进程或者远程进程

Java千百问_08JDK详解(019)_jdk工具包有哪些工具

点击进入_更多_Java千百问 jdk工具包有哪些工具 JDK工具包中提供了很多工具和实用的程序.涵盖了基本工具( javac, java, javadoc, apt, appletviewer, jar, jdb, javah, javap, extcheck),安全工具,国际化工具,RMI工具,IDL, RMI-IIOP工具,部署工具,java插件工具,java Web工具,监控管理工具,故障排查工具等. 这里我们只进行以下简单说明,不一一介绍,具体参见oracle官方文档:http://d

Java千百问_08JDK详解(012)_JPDA是什么

点击进入_更多_Java千百问 1.JPDA是什么 我们可以通过常见的Java IDE提供的图形界面调试工具进行代码调试,甚至可以使用JDK自带的jdb工具,以文本命令的形式来调试Java 程序,这些形形色色的调试工具都是通过JPDA开发的. JPDA(Java Platform Debugger Architecture)是 Java平台调试体系结构的缩写,通过JPDA提供的API,开发人员可以方便灵活的搭建Java调试工具. JPDA主要由三个部分组成:Java虚拟机工具接口(JVMTI,J

Java千百问_08JDK详解(008)_通过代码如何编译java文件

点击进入_更多_Java千百问 1.通过代码如何编译java文件 编译器是一个命令行工具(jdk自带的编译工具javac,了解javac看这里:javac是什么),但也可以使用API来调用(一般的IDE都会使用这一组API来封装自己的编译功能).编译器遵循Java语言规范(The Java Language Specification,JLS)和Java虚拟机规范(The Java Virtual Machine Specification,JVMS). 在Java 6之后,提供了标准包来操作J