前面有两篇铺垫博文,在博文《200303-如何优雅的在 java 中统计代码块耗时》,其最后提到了根据利用 java agent 来统计方法耗时
博文《200316-IDEA + maven 零基础构建 java agent 项目》中则详细描述了搭建一个 java agent 开发测试项目的全过程
本篇博文将进入 java agent 的实战,手把手教你如何是实现一个统计方法耗时的 java agent
- 基本姿势点
上面两节虽然手把手教你实现了一个 hello world 版 agent,然而实际上对 java agent 依然是一脸茫然,所以我们得先补齐一下基础知识
首先来看 agent 的两个方法中的参数 Instrumentation,我们先看一下它的接口定义
/**
- 注册一个Transformer,从此之后的类加载都会被Transformer拦截。
- Transformer可以直接对类的字节码byte[]进行修改
*/
void addTransformer(ClassFileTransformer transformer);
/**
- 对JVM已经加载的类重新触发类加载。使用的就是上面注册的Transformer。
- retransformation可以修改方法体,但是不能变更方法签名、增加和删除方法/类的成员属性
*/
void retransformClasses(Class<?>… classes) throws UnmodifiableClassException;
/**
- 获取一个对象的大小
*/
long getObjectSize(Object objectToSize);
/**
- 将一个jar加入到bootstrap classloader的 classpath里
*/
void appendToBootstrapClassLoaderSearch(JarFile jarfile);
/**
- 获取当前被JVM加载的所有类对象
*/
Class[] getAllLoadedClasses();
复制代码前面两个方法比较重要,addTransformer 方法配置之后,后续的类加载都会被 Transformer 拦截。对于已经加载过的类,可以执行 retransformClasses 来重新触发这个 Transformer 的拦截。类加载的字节码被修改后,除非再次被 retransform,否则不会恢复。
通过上面的描述,可知
可以通过Transfo