快速业务通道

深入Java调试体系,第2部分: JVMTI和Agent实现 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-19
。在断点发生的时候,虚拟机会触发一个事件,开发者可以使用在上文中介绍过的方式对事件进行处理。

JVMTI 数据结构

JVMTI 中使用的数据结构,首先也是一些标准的 JNI 数据结构,比如 jint,jlong ;其次,JVMTI 也定义了一些基本类型,比如 jthread,表示一个 thread,jvmtiEvent,表示 jvmti 所定义的事件;更复杂的有 JVMTI 的一些需要用结构体表示的数据结构,比如堆的信息(jvmtiStackInfo)。这些数据结构在文档中都有清楚的定义,本文就不再详细解释。

一个简单的 Agent 实现

下面将通过一个具体的例子,来阐述如何开发一个简单的 Agent 。这个 Agent 是通过 C++ 编写的(读者可以在最后下载到完整的代码),他通过监听 JVMTI_EVENT_METHOD_ENTRY 事件,注册对应的回调函数来响应这个事件,来输出所有被调用函数名。有兴趣的读者还可以参照这个基本流程,通过 JVMTI 提供的丰富的函数来进行扩展和定制。

Agent 的设计

具体实现都在 MethodTraceAgent 这个类里提供。按照顺序,他会处理环境初始化、参数解析、注册功能、注册事件响应,每个功能都被抽象在一个具体的函数里。

class MethodTraceAgent  {   public:     void Init(JavaVM *vm) const throw(AgentException);     void ParseOptions(const char* str) const throw(AgentException);     void AddCapability() const throw(AgentException);     void RegisterEvent() const throw(AgentException);     ...   private:     ...     static jvmtiEnv * m_jvmti;     static char* m_filter;  };

Agent_OnLoad 函数会在 Agent 被加载的时候创建这个类,并依次调用上述各个方法,从而实现这个 Agent 的功能。

JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved) {   ...   MethodTraceAgent* agent = new MethodTraceAgent();   agent->Init(vm);   agent->ParseOptions(options);   agent->AddCapability();   agent->RegisterEvent();   ... }

深入Java调试体系,第2部分: JVMTI和Agent实现(5)

时间:2011-02-14 IBM 吕晶 邱小侠

运行过程如图 1 所示:

图 1. Agent 时序图

深入Java调试体系,第2部分: JVMTI和Agent实现 - 编程入门网

Agent 编译和运行

Agent 的编译非常简单,他和编译普通的动态链接库没有本质区别,只是需要将 JDK 提供的一些头文件包含进来。

Windows: cl /EHsc -I${JAVA_HOME}\include\ -I${JAVA_HOME}\include\win32 -LD MethodTraceAgent.cpp Main.cpp -FeAgent.dll

Linux: g++ -I${JAVA_HOME}/include/ -I${JAVA_HOME}/include/linux MethodTraceAgent.cpp Main.cpp -fPIC -shared -o libagent.so

在附带的代码文件里提供了一个可运行的 Java 类,默认情况下运行的结果如下图所示:

图 2. 默认运行输出

深入Java调试体系,第2部分: JVMTI和Agent实现 - 编程入门网

现在,我们运行程序前告诉 Java 先加载编译出来的 Agent:

java -agentlib:Agent=first MethodTraceTest

这次的输出如图 3. 所示:

图 3. 添加 Agent 后输出

深入Java调试体系,第2部分: JVMTI和Agent实现 - 编程入门网

可以当程序运行到到 MethodTraceTest 的 first 方法是,Agent 会输出这个事件。“ first ”是 Agent 运行的参数,如果不指定话,所有的进入方法的触发的事件都会被输出,如果读者把这个参数去掉再运行的话,会发现在运行 main 函数前,已经有非常基本的类库函数被调用了。

结语

Java 虚拟机通过 JVMTI 提供了一整套函数来帮助用户检测管理虚拟机运行态,它主要通过 Agent 的方式实现与用户的互操作。本文简单介绍了 Agent 的实现方式和 JVMTI 的使用。通过 Agent 这种方式不仅仅用户可以使用,事实上,JDK 里面的很多工具,比如 Instrumentation 和 JDI,

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号