实现一个方法耗时统计的 java agent

个人博客导航页(点击右侧链接即可打开个人博客):大牛带你入门技术栈 

前面有两篇铺垫博文,在博文《200303-如何优雅的在 java 中统计代码块耗时》,其最后提到了根据利用 java agent 来统计方法耗时

博文《200316-IDEA + maven 零基础构建 java agent 项目》中则详细描述了搭建一个 java agent 开发测试项目的全过程

本篇博文将进入 java agent 的实战,手把手教你如何是实现一个统计方法耗时的 java agent

<!-- more -->

1. 基本姿势点

上面两节虽然手把手教你实现了一个 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,否则不会恢复。

通过上面的描述,可知

  • 可以通过Transformer修改类
  • 类加载时,会被触发 Transformer 拦截

2. 实现

我们需要统计方法耗时,所以想到的就是在方法的执行前,记录一个时间,执行完之后统计一下时间差,即为耗时

直接修改字节码有点麻烦,因此我们借助神器javaassist来修改字节码

实现自定义的ClassFileTransformer,代码如下

public class CostTransformer implements ClassFileTransformer {
    @Override
    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
            ProtectionDomain protectionDomain, byte[] classfileBuffer) {
        // 这里我们限制下,只针对目标包下进
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值