JVM源码分析之javaagent原理完全解读.docx

  1. 1、本文档共13页,可阅读全部内容。
  2. 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
JVM源码分析之javaagent原理完全解读

概述本文重点讲述javaagent的具体实现,因为它面向的是我们Java程序员,而且agent都是用Java编写的,不需要太多的C/C++编程基础,不过这篇文章里也会讲到JVMTIAgent(C实现的),因为javaagent的运行还是依赖于一个特殊的JVMTIAgent。对于javaagent,或许大家都听过,甚至使用过,常见的用法大致如下:java -javaagent:myagent.jar=mode=test Test我们通过-javaagent来指定我们编写的agent的jar路径(./myagent.jar),以及要传给agent的参数(mode=test),在启动的时候这个agent就可以做一些我们希望的事了。javaagent的主要功能如下:可以在加载class文件之前做拦截,对字节码做修改可以在运行期对已加载类的字节码做变更,但是这种情况下会有很多的限制,后面会详细说还有其他一些小众的功能获取所有已经加载过的类获取所有已经初始化过的类(执行过clinit方法,是上面的一个子集)获取某个对象的大小将某个jar加入到bootstrap classpath里作为高优先级被bootstrapClassloader加载将某个jar加入到classpath里供AppClassloard去加载设置某些native方法的前缀,主要在查找native方法的时候做规则匹配想象一下可以让程序按照我们预期的逻辑去执行,听起来是不是挺酷的。JVMTIJVMTI全称JVM Tool Interface,是JVM暴露出来的一些供用户扩展的接口集合。JVMTI是基于事件驱动的,JVM每执行到一定的逻辑就会调用一些事件的回调接口(如果有的话),这些接口可以供开发者扩展自己的逻辑。比如最常见的,我们想在某个类的字节码文件读取之后、类定义之前修改相关的字节码,从而使创建的class对象是我们修改之后的字节码内容,那就可以实现一个回调函数赋给jvmtiEnv(JVMTI的运行时,通常一个JVMTIAgent对应一个jvmtiEnv,但是也可以对应多个)的回调方法集合里的ClassFileLoadHook,这样在接下来的类文件加载过程中都会调用到这个函数中,大致实现如下:,jvmtiEventCallbacks callbacks;jvmtiEnv* jvmtienv =jvmti(agent);jvmtiError jvmtierror;memset(callbacks,0,sizeof(callbacks)); callbacks.ClassFileLoadHook =eventHandlerClassFileLoadHook;jvmtierror=(*jvmtienv)-SetEventCallbacks( jvmtienv,callbacks,sizeof(callbacks));JVMTIAgentJVMTIAgent其实就是一个动态库,利用JVMTI暴露出来的一些接口来干一些我们想做、但是正常情况下又做不到的事情,不过为了和普通的动态库进行区分,它一般会实现如下的一个或者多个函数:JNIEXPORT jint JNICALLAgent_OnLoad(JavaVM *vm,char*options,void*reserved);JNIEXPORT jint JNICALLAgent_OnAttach(JavaVM* vm,char* options,void* reserved);JNIEXPORT void JNICALLAgent_OnUnload(JavaVM *vm);Agent_OnLoad函数,如果agent是在启动时加载的,也就是在vm参数里通过-agentlib来指定的,那在启动过程中就会去执行这个agent里的Agent_OnLoad函数。Agent_OnAttach函数,如果agent不是在启动时加载的,而是我们先attach到目标进程上,然后给对应的目标进程发送load命令来加载,则在加载过程中会调用Agent_OnAttach函数。Agent_OnUnload函数,在agent卸载时调用,不过貌似基本上很少实现它。其实我们每天都在和JVMTIAgent打交道,只是你可能没有意识到而已,比如我们经常使用Eclipse等工具调试Java代码,其实就是利用JRE自带的jdwp agent实现的,只是Eclipse等工具在没让你察觉的情况下将相关参数(类似-agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:61349)自动加到程序启动参数列表里了,其中agentlib参数就用来跟要加载的agent的名字,比如这

文档评论(0)

tianma2015 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档