Java面试快问快答-Instrument机制

举报
JavaEdge 发表于 2021/06/04 00:14:25 2021/06/04
【摘要】 Java Instrument有什么作用? 使开发者可以构建一个独立于应用程序的代理程序Agent,用来监控和协助运行在JVM上的程序,更重要的是能够替换和修改某些类的定义; 最大的作用:可以实现一种虚拟机级别支持的AOP实现方式; 在JDK 1.5 、1.6中,Java Instrument做了哪些变动支持? JDK 1.5:支持静态Instrument,就是...

Java Instrument有什么作用?

使开发者可以构建一个独立于应用程序的代理程序Agent,用来监控和协助运行在JVM上的程序,更重要的是能够替换和修改某些类的定义;

最大的作用:可以实现一种虚拟机级别支持的AOP实现方式;

在JDK 1.5 、1.6中,Java Instrument做了哪些变动支持?

  • JDK 1.5:支持静态Instrument,就是在JVM启动前静态设置Instrument
  • JDK 1.6:支持动态Instrument,就是在JVM启动后动态设置Instrument;支持本地代码Instrument;支持动态改变classpath;

Java Instrument的实现是基于JVM什么机制?

基于JVMTI代理程序;
JVMTI:一套代理程序机制,为JVM相关工具提供的本地编程接口集合;
JVMTI可以支持第三方工具程序以代理的方式连接和访问JVM,并利用JVMTI提供的丰富的编程接口,完成很多跟JVM相关的功能;

Instrument premain、agentmain方法何时执行?

  • premain执行时机:在JVM启动时,初始化函数eventHandlerVMinit会调用sun.instrument.instrumentationImpl类的loadClassAndCallPremain方法去执行Premain-Class指定类的premain方法;
  • agentmain执行时机:在JVM启动后,通过VirtualMachine附着一个Instrument,如:vm.loadAgent(jar),会调用sun.instrument.instrumentationImpl类的loadClassAndCallAgentmain方法去执行Agentmain-Class指定类的agentmain方法;

Instrument premain、agentmain方法中两个参数agentArgs、inst代表什么?分别会有什么作用?

  • agentArgs:代理程序命令行中输入参数,随同“-javaagent”一起传入,与main函数不同的是,这个参数是一个字符串而不是一个字符串数组;
  • inst:java.lang.instrument.Instrumentation实例,由JVM自动传入,集中了几乎所有功能方法,如:类操作、classpath操作等;

java.lang.instrument.ClassFileTransformer 什么作用?

ClassFileTransformer当中的transform方法可以对类定义进行操作修改;

在类字节码载入JVM前,JVM会调用ClassFileTransformer.transform方法,从而实现对类定义进行操作修改,实现AOP功能;相对于JDK 动态代理、CGLIB等AOP实现技术,不会生成新类,也不需要原类有接口;
7 对于agentmain方法执行,如何进行动态attach agent?
通过VirtualMachine附着一个Instrument,如:vm.loadAgent(jar);

META-INF/MAINFEST.MF参数清单?

Premain-Class:指定包含premain方法的类名;
Agent-Class:指定包含agentmain方法的类名;
Boot-Class-Path:指定引导类加载器搜索的路径列表。查找类的特点于平台的机制失败后,引导类加载器会搜索这些路径;
Can-Redefine-Class:是否能重新定义此代理所需的类,默认为false;
Can-Retransform-Class:是否能重新转换此代理所需的类,默认为false;
Can-Set-Native-Method-Prefix:是否能设置此代理所需的本机方法前缀,默认值为false;

两个核心API ClassFileTransformer、Instrumention?

ClassFileTransformer:定义了类加载前的预处理类;
Instrumentation:增强器
(1)add/removeTransformer:添加/删除ClasFileTransformer;

(2)retransformerClasses:指定哪些类,在已加载的情况下,重新进行转换处理,即触发重新加载类定义;对于重新加载的类不能修改旧有的类声明,比如:不能增加属性、不能修改方法声明等;

(3)redefineClasses:指定哪些类,触发重新加载类定义,与上面不同的是不会重新进行转换处理,而是把处理结果bytecode直接给JVM;

(4)getAllLoadedClasses:获取当前已加载的Class集合;

(5)getInitiatedClasses:获取由某个特定ClassLoader加载的类定义;

(6)getObjectSize:获得一个对象占用的空间大小;

(7)appendToBootstrapClassLoaderSearch/appentToSystemClassLoaderSearch:增加BootstrapClassLoader/SystemClassLoader搜索路径;

(8)isNativeMethodPrefixSupported/SetNativeMethodPrefix:判断JVM是否支持拦截Native Method;

Java Instrument工作原理?

在JVM启动时,通过JVM参数-javaagent,传入agent jar,Instrument Agent被加载;
在Instrument Agent 初始化时,注册了JVMTI初始化函数eventHandlerVMinit;
在JVM启动时,会调用初始化函数eventHandlerVMinit,启动了Instrument Agent,用sun.instrument.instrumentationImpl类里的方法loadClassAndCallPremain方法去初始化Premain-Class指定类的premain方法;
初始化函数eventHandlerVMinit,注册了class解析的ClassFileLoadHook函数;
在解析Class之前,JVM调用JVMTI的ClassFileLoadHook函数,钩子函数调用sun.instrument.instrumentationImpl类里的transform方法,通过TransformerManager的transformer方法最终调用我们自定义的Transformer类的transform方法;
因为字节码在解析Class之前改的,直接使用修改后的字节码的数据流替代,最后进入Class解析,对整个Class解析无影响;
重新加载Class依然重新走5-6步骤;

文章来源: javaedge.blog.csdn.net,作者:JavaEdge.,版权归原作者所有,如需转载,请联系作者。

原文链接:javaedge.blog.csdn.net/article/details/105203881

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。