前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java Agent入门实战(二)-Instrumentation源码概述

Java Agent入门实战(二)-Instrumentation源码概述

作者头像
蒋老湿
发布2020-01-15 15:47:54
1.4K0
发布2020-01-15 15:47:54
举报
文章被收录于专栏:技术栈技术栈

Instrumentation接口设计初衷是为了收集Java程序运行时的数据,用于监控运行程序状态,记录日志,分析代码用的。接下来从源码的流程来介绍一下

实现类InstrumentationImpl的void addTransformer(ClassFileTransformer transformer, boolean canRetransform);

从这段代码知道,转换器ClassFileTransformer的实现是存储在TransformerManager的TransformerInfo数组中的,数组初始长度为0,每添加一个,数组长度为原来的长度+1,将原数组内容拷贝到新数组中。

VirtualMachine.attach

进入AttachProvider.providers(),这里面会初始化AttachProvider,并返回一个AttachProvider List

进入ServiceLoader.load(AttachProvider.class, AttachProvider.class.getClassLoader());

继续跟进方法 new LazyIterator(service, loader)

看一下com.sun.tools jar包下的META-INF/services/目录,打开 com.sun.tools.attach.spi.AttachProvider, 可以看到有不同平台操作系统的实现,我的是windows,会调用windos的实现sun.tools.attach.WindowsAttachProvider。其他的都被注释掉了。代码看到这,就知道ServiceLoader.load方法最终加载的是sun.tools.attach.WindowsAttachProvider

上文hasNextService()方法下面的nextService()

回到最初的VirtualMachine.attach(String var0)方法,进入return var4.attachVirtualMachine(var0);attachVirtualMachine()

通过 ClassLoader 类中的findNative方法,可以找到JVM源码中的一些native方法调用名,这样可以关联着JVM源码看底层的C++源码到底做了啥

发现在attach.dll中找方法名为Java_sun_tools_attach_WindowsVirtualMachine_openProcessnative method

尝试性的在jdk源码里去找这2个方法Java_sun_tools_attach_WindowsVirtualMachine_openProcessJava_sun_tools_attach_WindowsVirtualMachine_enqueue

virtualMachine.loadAgent()、 virtualMachine.detach()源码流程和上述类似,也和平台相关,这里就不在赘述了。

RedefineClasse配置注意事项

可以在运行期对已加载类的字节码做变更,但是这种情况下会有很多的限制 对比新老类,并要求如下:

  • 父类是同一个
  • 实现的接口数也要相同,并且是相同的接口
  • 类访问符必须一致
  • 字段数和字段名要一致
  • 新增的方法必须是 private static/final 的
  • 可以删除修改方法

参考

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020年01月06日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • VirtualMachine.attach
    • RedefineClasse配置注意事项
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档