亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

字節碼實戰--手寫一個btrace

標簽:
Java
简易的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

> 原创首发于慕课网

點擊查看更多內容
4人點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
JAVA開發工程師
手記
粉絲
1.6萬
獲贊與收藏
380

關注作者,訂閱最新文章

閱讀免費教程

感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消