`
victorzhzh
  • 浏览: 203033 次
  • 来自: ...
社区版块
存档分类
最新评论

Btrace系列之一:Btrace的基本原理

阅读更多

 

写在前面的话: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二三事之二:OnMethod子类匹配BUG(怀疑)

    本文将深入探讨“BTrace二三事之二:OnMethod子类匹配BUG(怀疑)”这一主题,结合源码分析和实际工具应用,揭示可能存在的问题及其解决策略。 首先,我们要理解BTrace的工作原理。BTrace是基于字节码注入的技术,它...

    BTrace实现原理

    【BTrace实现原理详解】 BTrace,一个强大的Java诊断工具,其主要功能是在线无侵入地对生产环境中的Java应用程序进行动态跟踪和性能分析。它的实现原理主要依赖于四个核心组件:Java Agent、ASM、Java Instrument ...

    btrace支持jdk1.7 linux下使用

    BTrace脚本由一系列探查点和相关操作组成,使用Java语法编写。开发者可以定义探查点触发时执行的代码,比如记录日志、计算性能指标等。`samples`目录中的脚本提供了很好的学习起点。 5. **BTrace的优势**: - **...

    btrace源代码

    5. **Performance Metrics**:BTrace提供了一系列性能指标,如CPU时间、线程状态转换等,帮助开发者了解程序的运行情况。通过这些指标,可以有效地定位性能瓶颈。 6. **安全机制**:为了防止误操作,BTrace实施了...

    btrace引导文件安装Btrace

    4. **查看结果**:Btrace会将监控数据实时显示在VisualVM中,你可以观察方法调用的频率、执行时间、对象创建等信息。 **Btrace 脚本编写** Btrace脚本使用Java语言编写,但添加了一些特定的API,如`@OnMethod`、`@...

    btrace-demo:demo项目

    2. **工作原理**:BTrace通过Java Agent机制,在JVM启动时动态地将BTrace脚本插入到目标应用中,然后在特定的触发条件(如方法调用、特定类加载等)下执行这些脚本。 3. **BTrace脚本**:BTrace使用一种类似于Java...

    Btrace 学习1

    BTrace 提供了一系列的内建脚本函数和注解,如 @OnMethod、@Trace、@BTrace、@Probe 等,方便开发者编写探针脚本。这些脚本通常用 Java 编写,可以访问诸如系统属性、线程信息、堆栈跟踪等各种运行时数据。 5. **...

    Btrace 官方zip包

    1. **类方法统计**:Btrace 可以帮助开发者追踪并统计应用程序中各个类方法的调用次数、执行时间等信息,这对于优化性能、定位热点代码至关重要。 2. **无侵略性监控**:由于Btrace 不修改原始代码,只是在运行时...

    btrace1.3.9

    2. **脚本编写**:BTrace使用一种简单的脚本语言,基于Groovy,开发者可以编写脚本来定义想要追踪的行为。例如,可以追踪方法调用、记录日志、计算性能指标等。 3. **安全机制**:BTrace有内置的安全策略,以防止不...

    jvisualvm btrace插件离线安装

    在Java开发领域,性能优化是不可或缺的一环,而BTrace作为一个强大的动态跟踪工具,可以帮助开发者实时监控和分析应用程序的行为。本文将详细介绍如何在jVisualVM上进行BTrace插件的离线安装,以便在无法在线安装的...

    btrace_extend-master

    2. **安全性**:BTrace使用JDK的动态代理机制,确保只在安全的点插入探查代码,避免引发运行时错误或性能下降。 3. **实时性能分析**:通过BTrace,你可以实时查看方法调用的时间、对象创建频率、内存分配情况等,...

    BTrace的安装包Windows

    BTrace是一款强大的Java应用程序动态跟踪工具,它允许开发者在不修改代码的情况下,对正在运行的应用进行诊断和性能分析。这款工具在Java社区中广受欢迎,因为它提供了灵活的探查(tracing)机制,能够帮助我们了解...

    Btrace资源

    它包含了运行Btrace服务端所需的基本环境和依赖。 **Btrace工作原理** Btrace利用了Java的 JVMTI (Java Virtual Machine Tool Interface) 技术,JVMTI允许外部工具如Btrace与Java虚拟机交互,提供诸如挂起线程、...

    btrace1.3.9.zip

    2. **btrace-agent-1.3.9.jar**:BTrace代理是实现动态代码插桩的关键组件。它会在应用程序启动时加载,并根据客户端提供的BTrace脚本,在目标类的字节码上进行插入操作。 3. **btrace-boot-1.3.9.jar**:这个文件...

    btrace release-1.2.5.1

    【标题】"btrace release-1.2.5.1" 指的是BTrace的一个特定版本,1.2.5.1。BTrace是一款强大的Java应用动态追踪工具,它允许开发者在运行时对Java应用程序进行性能分析和诊断,而无需修改源代码或重新部署应用。这个...

    btrace-release-1.3.11.3.zip

    3. **丰富的监控脚本**:Btrace 提供了一种基于 Java 的脚本语言,开发者可以创建自定义的监控脚本来追踪特定的行为或性能问题。 4. **安全性**:由于 Btrace 使用 Java 代理机制,只有具备权限的用户才能启用监控,...

    btrace支持jdk1.6上运行的版本

    5. **易用性**:BTrace 提供了一个简单的命令行界面和直观的脚本语法,使得开发者能够快速上手。 **三、BTrace 的使用步骤** 1. **安装**:下载 BTrace 并将其解压到本地目录,确保其与 JDK 1.6 或更高版本兼容。 ...

    jdk1.8-Btrace.rar

    【标题】"jdk1.8-Btrace.rar"指的是一个针对Java开发的特殊工具包,它包含了一个名为Btrace的在线检测插件。这个插件专为Java开发者设计,旨在帮助他们在应用程序运行时进行问题的实时定位,而无需停止或重启服务。...

Global site tag (gtag.js) - Google Analytics