一、背景
在生产环境中可能经常遇到各种问题,定位问题需要获取程序运行时的数据信息,如方法参数、返回值、全局变量、堆栈信息等。为了获取这些数据信息,我们可以 通过改写代码,增加日志信息的打印,再发布到生产环境。通过这种方式,一方面将增大定位问题的成本和周期,对于紧急问题无法做到及时响应;另一方面重新部 署后环境可能已被破坏,很难重新问题的场景。
二、BTrace功能
BTrace天生就为解决这类问题而来,它可以动态地跟踪java运行程序。通过hotswap技术,动态将跟踪字节码注入到运行类中,对运行代码侵入较小,对性能上的影响可以忽略不计。
BTrace在使用上有很多限制条件,如不能创建对象、数组、抛出和捕获异常、循环等,具体限制条件参考用户文档中的BTrace Restrictions。用户文档地址: http://kenai.com/projects/btrace/pages/UserGuide。
根据官方声明,不当地使用btrace可能导致jvm崩溃,如BTrace使用错误的.class文件,Hotspot JVM自身存在的hotswap bug等。可以先在本地验证BTrace脚本的正确性,再传到生产环境中定位问题。
三、安装步骤
1. 下载安装压缩包,最新版本的是1.2.1,下载地址: http://kenai.com/projects/btrace/downloads/directory/releases。
2. 解压缩,命令脚本放在bin目录中。
3. 设置脚本环境变量。
4. 增加脚本可执行权限。
四、使用方法
BTrace主要包含btracec和btrace两个命令编译和启动BTrace脚本:
1. btrace
功能: 用于运行BTrace跟踪程序。
命令格式:
btrace [-I <include-path>] [-p <port>] [-cp <classpath>] <pid> <btrace-script> [<args>]
示例:
btrace -cp build/ 1200 AllCalls1.java
参数含义:
include-path指定头文件的路径,用于脚本预处理功能,可选;
port指定BTrace agent的服务端监听端口号,用来监听clients,默认为2020,可选;
classpath用来指定类加载路径,默认为当前路径,可选;
pid表示进程号,可通过jps命令获取;
btrace-script即为BTrace脚本;btrace脚本如果以.java结尾,会先编译再提交执行。可使用btracec命令对脚本进行预编译。
args是BTrace脚本可选参数,在脚本中可通过"$"和"$length"获取参数信息。
2. btracec
功能: 用于预编译BTrace脚本,用于在编译时期验证脚本正确性。
btracec [-I <include-path>] [-cp <classpath>] [-d <directory>] <one-or-more-BTrace-.java-files>
参数意义同btrace命令一致,directory表示编译结果输出目录。
3. btracer
功能: btracer命令同时启动应用程序和BTrace脚本,即在应用程序启动过程中使用BTrace脚本。而btrace命令针对已运行程序执行BTrace脚本。
命令格式:
btracer <pre-compiled-btrace.class> <application-main-class> <application-args>
参数说明:
pre-compiled-btrace.class表示经过btracec编译后的BTrace脚本。
application-main-class表示应用程序代码;
application-args表示应用程序参数。
该命令的等价写法为:
java -javaagent:btrace-agent.jar=script=<pre-compiled-btrace-script1>[,<pre-compiled-btrace-script1>]* <MainClass> <AppArguments>
4. jvisualvm插件
BTrace提供了jvisualvm插件,强烈推荐在jvisualvm中编写和测试BTrace脚本,启动、关闭、发送事件、增加classpath都非常方便。
五、BTrace实战
1. 示例代码
示例代码定义了Counter计数器,有一个add()方法,每次增加随机值,总数保存在totalCount属性中。
- package com.learnworld;
- import java.util.Random;
- public class BTraceTest {
- public static void main(String[] args) throws Exception {
- Random random = new Random();
- // 计数器
- Counter counter = new Counter();
- while (true) {
- // 每次增加随机值
- counter.add(random.nextInt(10));
- Thread.sleep(1000);
- }
- }
- }
- package com.learnworld;
- public class Counter {
- // 总数
- private static int totalCount = 0;
- public int add(int num) throws Exception {
- totalCount += num;
- sleep();
- return totalCount;
- }
- public void sleep() throws Exception {
- Thread.sleep(1000);
- }
- }
2. 常见使用场景
下面通过几个常见使用场景演示如何使用BTrace脚本。
1) 获取add()方法参数值和返回值。
- import com.sun.btrace.annotations.*;
- import static com.sun.btrace.BTraceUtils.*;
- @BTrace
- public class TracingScript {
- @OnMethod(
- clazz="com.learnworld.Counter",
- method="add",
- location=@Location(Kind.RETURN)
- )
- public static void traceExecute(int num,@Return int result){
- println("====== ");
- println(strcat("parameter num: ",str(num)));
- println(strcat("return value:",str(result)));
- }
- }
2) 定时获取Counter类的属性值totalCount。
- import com.sun.btrace.annotations.*;
- import static com.sun.btrace.BTraceUtils.*;
- @BTrace
- public class TracingScript {
- private static Object totalCount = 0;
- @OnMethod(
- clazz="com.learnworld.Counter",
- method="add",
- location=@Location(Kind.RETURN)
- )
- public static void traceExecute(@Self com.learnworld.Counter counter){
- totalCount = get(field("com.learnworld.Counter","totalCount"), counter);
- }
- @OnTimer(1000)
- public static void print(){
- println("====== ");
- println(strcat("totalCount: ",str(totalCount)));
- }
- }
3) 获取add方法执行时间。
- import com.sun.btrace.annotations.*;
- import static com.sun.btrace.BTraceUtils.*;
- @BTrace
- public class TracingScript {
- @TLS private static long startTime = 0;
- @OnMethod(
- clazz="com.learnworld.Counter",
- method="add"
- )
- public static void startExecute(){
- startTime = timeNanos();
- }
- @OnMethod(
- clazz="com.learnworld.Counter",
- method="add",
- location=@Location(Kind.RETURN)
- )
- public static void endExecute(@Duration long duration){
- long time = timeNanos() - startTime;
- println(strcat("execute time(nanos): ", str(time)));
- println(strcat("duration(nanos): ", str(duration)));
- }
- }
4) 获取add()方法调用方法sleep()次数。
- import com.sun.btrace.annotations.*;
- import static com.sun.btrace.BTraceUtils.*;
- @BTrace
- public class TracingScript {
- private static long count;
- @OnMethod(
- clazz="/.*/",
- method="add",
- location=@Location(value=Kind.CALL, clazz="/.*/", method="sleep")
- )
- public static void traceExecute(@ProbeClassName String pcm, @ProbeMethodName String pmn,
- @TargetInstance Object instance, @TargetMethodOrField String method){
- println("====== ");
- println(strcat("ProbeClassName: ",pcm));
- println(strcat("ProbeMethodName: ",pmn));
- println(strcat("TargetInstance: ",str(classOf(instance))));
- println(strcat("TargetMethodOrField : ",str(method)));
- count++;
- }
- @OnEvent
- public static void getCount(){
- println(strcat("count: ", str(count)));
- }
- }
六、参考文档
1. userGuide: http://kenai.com/projects/btrace/pages/UserGuide
2. JAVA doc: http://btrace.kenai.com/javadoc/1.2/index.html
3. BTrace用户手册<译>,http://macrochen.iteye.com/blog/838920
4. btrace使用简介,http://rdc.taobao.com/team/jm/archives/509
5. btrace记忆,http://agapple.iteye.com/blog/962119
6. btrace一些你不知道的事(源码入手),http://agapple.iteye.com/blog/1005918
http://learnworld.iteye.com/blog/1402763
相关推荐
这是一个用于演示btrace功能的demo程序, 其中TestJar4是源码,使用maven作为项目管理工具 TestJar4-0.0.1-SNAPSHOT.jar为maven构建之后的jar包 AllMethod.java是trace script
扩展之后的btrace功能使用时都不需要写btrace脚本。 2.使用接口时间监控功能,命令格式为btrace -E mCall pid clazz method,其中clazz 为需要监控的方法所在的类,method为需要监控的方法名称。例如btrace -E mCall...
7. docs:这个目录下通常包含BTrace的用户手册、API文档和其他技术文档,是学习和理解BTrace功能和工作原理的关键资源。 8. bin:这个目录存放可执行文件和脚本,如BTrace的命令行工具,用户可以直接运行这些文件来...
对于想要深入了解或定制BTrace功能的开发者来说,这是一个重要的资源。通过阅读源代码,我们可以理解其内部实现机制;通过示例,我们可以学习如何使用BTrace进行性能分析。 总的来说,BTrace是一个强大的Java性能...
8. **构建文件`: `build`目录可能包含构建BTrace的脚本或配置,这对于开发者想要定制或扩展BTrace功能时非常有用。 通过BTrace,开发者能够深入理解程序的运行状态,定位性能瓶颈,诊断并发问题,以及实施细粒度的...
【描述】"java 在线检测插件Btrace, 无需重启服务,即可在线定位问题"揭示了Btrace的核心功能。Btrace提供了一种动态跟踪Java应用程序的方法,可以在不中断服务的情况下,对代码执行路径进行监控和分析。这包括追踪...
jVisualVM是Java SDK附带的一款多合一的Java应用程序性能分析工具,它提供了丰富的功能,如内存分析、线程分析、JMX连接、采样剖析等。而BTrace则是Oracle公司推出的一个开源项目,允许开发者在运行时对Java应用进行...
Btrace利用了Java的 JVMTI (Java Virtual Machine Tool Interface) 技术,JVMTI允许外部工具如Btrace与Java虚拟机交互,提供诸如挂起线程、修改类、获取堆信息等功能。Btrace通过分析和修改类文件,实现在运行时动态...
### 二、Btrace 的主要功能 1. **类方法统计**:Btrace 可以帮助开发者追踪并统计应用程序中各个类方法的调用次数、执行时间等信息,这对于优化性能、定位热点代码至关重要。 2. **无侵略性监控**:由于Btrace 不...
BTrace利用Java的JVMTI(Java Virtual Machine Tool Interface)和Serviceability Agent(SA)来提供安全、低侵入性的生产环境中的代码探查功能。 【描述】"btrace1.3.9最新版本转过来"意味着这个压缩包包含了...
开发人员可以使用这个库来编写自定义的BTrace脚本,以实现特定的监控功能。 2. **btrace-agent-1.3.9.jar**:BTrace代理是实现动态代码插桩的关键组件。它会在应用程序启动时加载,并根据客户端提供的BTrace脚本,...
BTrace Workbench则是BTrace的集成环境,它扩展了jvisualvm的功能,让开发者能够更方便地创建、调试和应用BTrace脚本。 【描述】"btrace workbench 插件jar包打包下载,jvisualvm的插件" 指出,这个资源是一个可以...
它通过字节码增强技术来实现这一功能,对于理解复杂系统的行为和性能问题特别有用。 描述虽然为空,但我们可以根据标题推测,这篇博文可能讲述了如何使用bTrace来跟踪Java应用程序中的线程堆栈信息。线程堆栈是程序...
5. **可扩展性**:Btrace 支持与其他监控工具集成,例如日志记录框架、告警系统等,可以轻松地扩展其功能。 在 `btrace-release-1.3.11.3` 压缩包中,可能包含以下文件和目录: - `bin/`:包含 Btrace 的可执行...
4. **可扩展性**:BTrace 脚本可以根据需求进行定制,提供高度灵活的监控和分析功能。 5. **易用性**:BTrace 提供了一个简单的命令行界面和直观的脚本语法,使得开发者能够快速上手。 **三、BTrace 的使用步骤** ...
【标题】"btrace_extend-master" 是一个与BTrace工具相关的扩展项目,它提供了一些额外的功能和增强,以便更好地监控和诊断Java应用程序。BTrace是一款强大的动态代码分析工具,允许开发者在运行时对Java应用程序...
### 功能特性 1. **实时性**:BTrace可以在不中断应用程序运行的情况下收集数据,这对于线上环境的性能监控和问题定位尤其有用。 2. **无侵入性**:由于不需要修改源代码,BTrace降低了对原有程序的影响。 3. **...
BTrace,一个强大的Java诊断工具,其主要功能是在线无侵入地对生产环境中的Java应用程序进行动态跟踪和性能分析。它的实现原理主要依赖于四个核心组件:Java Agent、ASM、Java Instrument API以及Java Compiler API...
通过对BTrace源代码的深入研究,我们可以更好地理解其设计思路,学习如何利用BTrace进行生产环境的性能调试,甚至可以扩展其功能以满足更复杂的监控需求。BTrace的开源特性也鼓励社区成员参与进来,共同推动其发展,...
BTrace通过字节码注入技术实现其功能。它会在类加载时动态修改类的字节码,插入追踪代码,而无需修改原有源代码。这使得BTrace成为一种非常灵活的诊断工具,尤其适合生产环境,因为它不会影响程序的正常执行流程。 ...