伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

大白话JavaAgent

来源:本站原创 浏览:115次 时间:2022-10-19
一、JavaAgent是什么?

JDK5中只能通过命令行参数在启动JVM时指定javaagent参数来设置代理类,而JDK6中已经不仅限于在启动JVM时通过配置参数来设置代理类,JDK6中通过 Java Tool API 中的 attach 方式,我们也可以很方便地在运行过程中动态地设置加载代理类,以达到 instrumentation 的目的。 Instrumentation 的最大作用,就是类定义动态改变和操作。

二、JavaAgent能干什么?

javaagent的主要的功能如下:

  • 可以在加载class文件之前做拦截把字节码做修改

  • 可以在运行期将已经加载的类的字节码做变更,但是这种情况下会有很多的限制

  • 还有其他的一些小众的功能

    • 获取所有已经被加载过的类

    • 获取所有已经被初始化过了的类(执行过了clinit方法,是上面的一个子集)

    • 获取某个对象的大小

    • 将某个jar加入到bootstrapclasspath里作为高优先级被bootstrapClassloader加载

    • 将某个jar加入到classpath里供AppClassloard去加载

    • 设置某些native方法的前缀,主要在查找native方法的时候做规则匹配

想象一下可以让程序按照我们预期的逻辑去执行,听起来是不是挺酷的。

三、一个简单的 Agent 实现

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

Agent 的设计

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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 的功能。

1

2

3

4

5

6

7

8

9

10

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();

    ...

}

运行过程如图 1 所示:

图 1. Agent 时序图

Agent 编译和运行

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

  • Windows:

    1

    2

    cl /EHsc -I${JAVA_HOME}\include\ -I${JAVA_HOME}\include\win32

    -LD MethodTraceAgent.cpp Main.cpp -FeAgent.dll

  • Linux:

    1

    2

    g++ -I${JAVA_HOME}/include/ -I${JAVA_HOME}/include/linux

    MethodTraceAgent.cpp Main.cpp -fPIC -shared -o libagent.so

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

图 2. 默认运行输出

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

1

java -agentlib:Agent=first MethodTraceTest

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

图 3. 添加 Agent 后输出

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

 

四、总结

Java 虚拟机通过 JVMTI 提供了一整套函数来帮助用户检测管理虚拟机运行态,它主要通过 Agent 的方式实现与用户的互操作。通过 Agent 这种方式不仅仅用户可以使用,事实上,JDK 里面的很多工具,比如 Instrumentation 和 JDI, 都采用了这种方式。这种方式无需把这些工具绑定在虚拟机上,减少了虚拟机的负荷和内存占用。


  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net