写在前面的话:Btrace系列是我将平时里学习和使用Btrace的一些经验的总结,拿出来和大家一起交流一下,希望在这个过程中能找寻出自己理解或使用上的错误之处。
一、Btrace的简介:
Btrace是由Kenai
开发的一个开源项目,是一种动态跟踪分析JAVA源代码的工具。它可以用来帮我们做运行时的JAVA程序分析,监控等等操作,当然,它也不是万能的,BTrace也有一些使用上的限制,如:不能在脚本中新建类等等,这些在官方网站上有很详细的介绍,大家有兴趣可以查看:http://kenai.com/projects/btrace/pages/UserGuide。
二、JDK6的几个新特性:
Btrace是由:Attach API + BTrace脚本解析引擎 + ASM + JDK6 Instumentation组成,这里要注意最后一项是JDK6的Instumentation,为什么一定要是JDK6呢?我们就要来看一下JDK6为我们提供了什么:
1、虚拟机启动后的Instumentation:
Instumentation早在JDK5的时候就已经提出了,但是它有个局限性,premain函数只能在main函数之前被运行(对于Instumentation不熟悉的请去Sun官网查看),而JDK6之后提供了一个叫做agentmain的函数,它可以在main函数运行后在运行,代码如下:
public static void agentmain(String args, Instrumentation inst)
public static void agentmain(String args)
这个函数的功能通premain函数一样,可以对类进行各种操作。同premain函数一样,在manifest 文件里面设置“Agent-Class”来指定包含 agentmain 函数的类。
2、Instumentation提供的新方法retransformClasses:
这个新方法可以在agentmain函数中调用,它的功能和redefineClasses 一样,可以修改类的定义且是批量的。
3、BootClassPath和SystemClassPath的动态指定:
在JDK6之前,我们知道可以通过系统参数或者虚拟机启动参数,设置一个虚拟机运行时的boot class加载路径和system class加载路径,但是在启动后,这个路径是不可以修改的,并且,我们要在启动后再去加载一个*.jar文件是不可能的,但是在JDK6以后,这个规定被打破了,可以使用Instrumentation的appendToBootstrapClassLoaderSearch和appendToSystemClassLoaderSearch来修改路径或加载新的*.jar(注意:虽然实际的classpath被修改了,但是在property中的java.class.path却没有受任何影响)。
正因为以上的新特性,才缔造出了Btrace的想法以至于最后的实现。
三、Btrace的原理:
Btrace首先是通过Attach API中提供的VirtualMachine.attach(PID)方法来获得要监控的JVM,然后使用VirtualMachine.loadAgent("*.jar")方法来加载jar文件,这个jar文件中会包含Btrace的一个很重要的类com.sun.btrace.agent.Main,这个类里定义了如下的函数:
public static void premain(String args, Instrumentation inst) {
main(args, inst);
}
public static void agentmain(String args, Instrumentation inst) {
main(args, inst);
}
这里两个函数都调用了一个main方法,如下:
private static synchronized void main(final String args, final Instrumentation inst) {
......
inst.appendToBootstrapClassLoaderSearch(new JarFile(new File(path)));
......
inst.appendToSystemClassLoaderSearch(new JarFile(new File(path)));
......
startServer();
}
这里省去了不必要的代码,主要三行代码,头两行不用解释,上面已经说过用途了,第三行解释一下,代码如下:
private static void startServer() {
......
while (true) {
try {
......
handleNewClient(client);
} catch (RuntimeException re) {
if (isDebug()) debugPrint(re);
} catch (IOException ioexp) {
if (isDebug()) debugPrint(ioexp);
}
}
}
关键看一下handleNewClient(client)方法的调用,这个是修改类定义的地方,如下:
private static void handleNewClient(final Client client) {
......
inst.addTransformer(client, true);
......
inst.retransformClasses(classes);
}
这两句话就实现了对现有内存中的类定义的替换,当在一次调用new创建一个新对象时就会使用新的类定义,而老的已经生成的类对象是不会收到干扰的。
那又是谁取执行了对类定义的修改呢,这个是由BTrace脚本解析引擎 + ASM来实现的,脚本引擎负责解析我们所写的脚本,而ASM来对JAVA的字节码进行增强修改。你在Btrace的com.sun.btrace.agent.Client中可以看到ASM的影子,代码如下:
abstract class Client implements ClassFileTransformer, CommandListener {
static {
ClassFilter.class.getClass();
ClassReader.class.getClass();
ClassWriter.class.getClass();
......
}
private byte[] instrument(Class clazz, String cname, byte[] target) {
byte[] instrumentedCode;
try {
ClassWriter writer = InstrumentUtils.newClassWriter(target);
ClassReader reader = new ClassReader(target);
Instrumentor i = new Instrumentor(clazz, className, btraceCode, onMethods, writer);
......
}
现在我们在回顾一下整个流程,用Attach API附加*.jar然后使用BTrace脚本解析引擎 + ASM来实现对类的修改,在使用Instumentation实现类的内存替换,完毕!perfect!BTrace原来也就这么回事,但是我们不得不佩服开发团队的思维和整合能力,向牛人致敬!
分享到:
相关推荐
BTrace测试,参考:http://learnworld.iteye.com/blog/1402763
BTrace整个实现的原理是Java Agent+ASM+Java instrument+ Java Complier Api
NULL 博文链接:https://sswh.iteye.com/blog/1820391
btrace btrace btrace btrace
Btrace:java性能调优及问题追踪工具 Btrace:java性能调优及问题追踪工具
1.btrace扩展是在btrace已由功能上进行的扩展,原有功能和使用方式依然没变。目前版本扩展了两个功能:接口时间监控和接口时间调用树监控。扩展之后的btrace功能使用时都不需要写btrace脚本。 2.使用接口时间监控...
linux和windows通用,1.3.11...BTrace是一种安全,动态的Java跟踪工具。BTrace通过动态(字节码)检测正在运行的Java程序的类来工作。BTrace将跟踪操作插入到正在运行的Java程序的类中,并对跟踪的程序类进行热交换。
btrace1.3.9 jdk1.8 maven 编译构建 http://github.com/btraceio/btrace
btrace-demo 示范项目
java 在线检测插件Btrace, 无需重启服务,即可在线定位问题
btrace1.3.9最新版本转过来
btrace api 1.2 文档,从网上扒下来自己做的,其他地方貌似都没有...btrace是一个跟踪、监控java程序的小工具,能够在不改变源代码的情况下监控很多东西,比如:方法运行时间、输入输出参数、抛出的异常、调用的次数等
自己做的BTrace监控,Linux服务器上的tomcat工程,压缩包包含BTrace开发所需的jar包 BTrace简单示例代码 jvisualvm.exe如果远程服务器监控JVM虚拟机信息
BTrace可用于动态跟踪正在运行的Java程序(类似于DTrace for OpenSolaris应用程序)。 BTrace动态地测试目标应用程序的类以注入跟踪代码(“字节代码跟踪”)。
jvisualvm-btrace离线安装包。 jvisualvm btrace插件离线安装包1.2.85版本,目前官网不支持国内在线下载。 含相关依赖包:...安装时点工具-插件-已下载,点添加插件一次性将4个插件都添加进去,再点安装即可。
btrace安装包,linux和windows通用,1.3.9版本。可以直接解压缩配置环境变量后运行使用
Btrace用来做项目检测,访问过的类方法统计,无侵略性,JDK1.6
jvisualvm btrace插件离线安装,如果jvisualvm不能安装btrace,则可进行离线安装。 这里收集了安装btrace所需要的依赖包,直接添加 即可安装
Btrace Java 发布版本,Java 虚拟机监控程序