字节码实战--手写一个btrace

简介: 简易的btrace需求偶现的方法执行慢,我们是可以用jstack捕捉到的,但是慢到什么地步却是不一定知道的,现在就需要在不重启应用的情况下,获取方法执行的时间。

简易的btrace需求

偶现的方法执行慢,我们是可以用jstack捕捉到的,但是慢到什么地步却是不一定知道的,现在就需要在不重启应用的情况下,获取方法执行的时间。

需求特点

  1. 应用不重启
  2. 获取方法执行时间

技术选型

想要打印出时间,起码想到的是aop的方式。常规的方法是必须重启应用才能加的,典型的就是spring的aop,如果允许修改代码的话可以使用动态代理,或者自己写死到代码里。

操作方案

动态代理或者写死到代码

这种情况对代码的入侵太高了,如果要去掉这个功能,修改代码也是很麻烦的。

spring aop

这个需要依赖spring框架来做。可以不修改代码,但是不能做到动态生效。

javaagent

javaagent在1.6之后可以使用远程attach的方式,进行类的重新转化。这个是满足需求的。这个不了解的话可以去网上查查看。

字节码增强技术

方式选择好以后,那么关键点就是如何选择修改字节码的框架。

javassist

javassist是相对好用的,不过他想要在一个方法前后加代码,是通过方法包装来的,就是命名一个新的方法名和现在执行的方法名一样,然后把旧的方法重新命名。流程如下:
转化前:

 public void hello(){
        int a=0;
}

转化后

public void hello(){
    xxx
    helloxx();
    xxx
}

 public void helloxx(){
        int a=0;
}

这种情况是transform的做法,但是retransform有不能新增方法的限制。jdk的文档描述如下

The retransformation must not add, remove or rename fields or methods, change the signatures of methods, or change inheritance.

asm

asmapi操作比较麻烦。但是可以直接修改方法体的内容。
转化前:

 public void hello(){
        int a=0;
}

转化后:

 public void hello(){
        xxx
        int a=0;
        xxx
}

asm的做法也有两种方式,一种是增加方法调用,然后把传递的值保存在threadlocal里,另外一种就是把所有的内容写到方法里中。这两种都可以满足需求,第一种实现方式还简单一些,不用新增本地变量。

实现方式

修改字节码的代码比较枯燥,所有直接附上代码地址,此次使用的是asm增加方法局部变量的方式做的,这样的demo网上博客没有,asm的手册中也没有这样的例子,如果有兴趣的可以去看看
https://github.com/xpbob/lightTrace

目录
相关文章
|
Web App开发 缓存 JavaScript
图解 Google V8 # 13:字节码(一):V8为什么又重新引入字节码?
图解 Google V8 # 13:字节码(一):V8为什么又重新引入字节码?
305 0
图解 Google V8 # 13:字节码(一):V8为什么又重新引入字节码?
|
5月前
|
Java Maven 编译器
Java编译器注解运行和自动生成代码问题之@AutoService工作问题如何解决
Java编译器注解运行和自动生成代码问题之@AutoService工作问题如何解决
240 1
|
3月前
|
Arthas Java 测试技术
Java字节码文件、组成,jclasslib插件、阿里arthas工具,Java注解
Java字节码文件、组成、详解、分析;常用工具,jclasslib插件、阿里arthas工具;如何定位线上问题;Java注解
Java字节码文件、组成,jclasslib插件、阿里arthas工具,Java注解
|
5月前
|
Java 程序员 C++
大牛程序员用Java手写JVM:刚好够运行 HelloWorld
大牛程序员用Java手写JVM:刚好够运行 HelloWorld
|
5月前
|
Java 测试技术 Maven
Java编译器注解运行和自动生成代码问题之在编译时需要设置-proc:none参数问题如何解决
Java编译器注解运行和自动生成代码问题之在编译时需要设置-proc:none参数问题如何解决
|
5月前
|
Java 编译器
Java编译器注解运行和自动生成代码问题之运行时注解问题如何解决
Java编译器注解运行和自动生成代码问题之运行时注解问题如何解决
|
5月前
|
存储 Java
JAVA程序运行问题之编译生成的字节码在不同的平台上是否相同如何解决
JAVA程序运行问题之编译生成的字节码在不同的平台上是否相同如何解决
|
Java 数据库连接 数据库
【JavaSE专栏60】静态代码块,Java类加载过程中执行的一段代码
【JavaSE专栏60】静态代码块,Java类加载过程中执行的一段代码
|
Java Android开发
Java 编译时注解 —— 入门教程
Java 编译时注解 —— 入门教程
|
JavaScript IDE Java
【Java面试】什么是字节码?采用字节码的好处是什么?
【Java面试】什么是字节码?采用字节码的好处是什么?
207 0