该篇文章为译稿,原稿在:http://kenai.com/projects/btrace/pages/UserGuide#btrace_anno
包括本文提到的sample代码也在原稿中有连接。
Btrace的API在:http://btrace.kenai.com/javadoc/1.2/index.html
BTrace(https://btrace.dev.java.net/
)
是一个非常不错的
java
诊断工具
,
最近试着用了一下
,
文档比较少
,
主要是看例子吧
.
BTrace
中的
B
表示
bytecode,
表明它是在字节码层面上对代码进行
trace
用来在运行中的
java
类中注入
trace
代码
,
并对运行中的目标程序进行热交换
(hotswap)
btrace还提供了VisualVM Plugin 以及Netbeans Plugin
术语
Probe Point
在何处执行
trace
语句
,
这里的
"
何处
"
可以是具体的跟踪地点和执行事件
,
在
BTrace
中通过各种注解来指定
Trace Actions or Actions
在何时执行
trace
语句
Action Methods
定义在
trace
脚本中的
trace
语句
,
具体来说就是脚本中的无返回值静态方法
(1.2
之后可以是非静态方法
)
BTrace
限制
为了保证
trace
语句只读
, BTrace
对
trace
脚本有一些限制
(
比如不能改变被
trace
代码中的状态
)
·
BTrace class
不能新建类
,
新建数组
,
抛异常
,
捕获异常
,
·
不能调用实例方法以及静态方法
(com.sun.btrace.BTraceUtils
除外
)
·
不能将目标程序和对象赋值给
BTrace
的实例和静态
field
·
不能定义外部
,
内部
,
匿名
,
本地类
·
不能有同步块和方法
·
不能有循环
·
不能实现接口
,
不能扩展类
·
不能使用
assert
语句
,
不能使用
class
字面值
BTrace步骤
1.取得目标java进程id(pid)
2.编写BTrace脚本
3.执行命令行:
btrace <pid> <自己定制的脚本> <输出文件>
eg:btrace 3045PrintExecuteTime.java > time.log
完整的BTrace命令:
引用
btrace [-I <include-path>] [-p <port>] [-cp <classpath>] <pid> <btrace-script> [<args>]
- -I 没有这个表明跳过预编译
- include-path: 指定用来编译脚本的头文件路径(关于预编译可参考例子ThreadBean.java)
- port : btrace agent端口, 默认是2020
- classpath : 编译所需类路径, 一般是指btrace-client.jar等类所在路径
- pid : java进程id
- btrace-script: btrace脚本, 如果是java文件, 则是未编译, class文件, 则是已编译过的
- args: 传递给btrace脚本的参数, 在脚本中可以通过$(), $length()来获取这些参数(定义在BTraceUtils中)
预编译BTrace脚本命令
引用
btracec [-I <include-path>] [-cp <classpath>] [-d <directory>] <one-or-more-BTrace-.java-files>
参数和上面大同小异, btracec 是一个类似javac的程序, 使用该程序编译, 将根据BTrace的限制条件进行严格检查
在目标程序中启动BTrace Agent
这个主要针对需要在目标程序启动的时候就需要trace其行为的场景, 此时BTrace agent将与目标程序一起启动(前提是必须对BTrace脚本进行预编译)
命令行:
引用
java
-javaagent:btrace-agent.jar=script=<pre-compiled-btrace-script1>[,<pre-compiled-btrace-script1>]*
<MainClass> <AppArguments>
方法上的注解
- @com.sun.btrace.annotations.OnMethod
用来指定trace的目标类和方法以及具体位置, 被注解的方法在匹配的方法执行到指定的位置会被调用. "clazz"属性用来指定目标类名,
可以指定全限定类名, 比如"java.awt.Component", 也可以是正则表达式(表达式必须写在"//"中,
比如"/java\\.awt\\..+/"). "method"属性用来指定被trace的方法.
表达式可以参考自带的例子(NewComponent.java 和 Classload.java,
关于方法的注解可以参考MultiClass.java). 有时候被trace的类和方法可能也使用了注解.
用法参考自带例子WebServiceTracker.java. 针对注解也是可以使用正则表达式,
比如像这个"@/com\\.acme\\..+/ ", 也可以通过指定超类来匹配多个类,
比如"+java.lang.Runnable"可以匹配所有实现了java.lang.Runnable接口的类.
具体参考自带例子SubtypeTracer.java.
- @com.sun.btrace.annotations.OnTimer 用来指定时长(ms)执行一次trace. 时长通过"value"属性指定. 具体参考自带例子 Histogram.java
- @com.sun.btrace.annotations.OnError 当trace代码抛异常时该注解的方法会被执行. 如果同一个trace脚本中其他方法抛异常, 该注解方法也会被执行.
- @com.sun.btrace.annotations.OnExit 当trace方法调用内置exit(int)方法(用来结束整个trace程序)时, 该注解的方法会被执行. 参考自带例子ProbeExit.java.
- @com.sun.btrace.annotations.OnEvent
用来截获"外部"btrace client触发的事件, 比如按Ctrl-C 中断btrace执行时将执行使用了该注解的方法,
该注解的value值为具体事件名称. 具体参考例子HistoOnEvent.java
- @com.sun.btrace.annotations.OnLowMemory 当内存超过某个设定值将触发该注解的方法, 具体参考MemAlerter.java
- @com.sun.btrace.annotations.OnProbe //我也没搞明白:(
参数上的注解
- @com.sun.btrace.annotations.Self 用来指定被trace方法的this, 可参考例子AWTEventTracer.java 和 AllCalls1.java
- @com.sun.btrace.annotations.Return 用来指定被trace方法的返回值, 可参考例子Classload.java
- @com.sun.btrace.annotations.ProbeClassName (since 1.1) 用来指定被trace的类名, 可参考例子AllMethods.java
- @com.sun.btrace.annotations.ProbeMethodName (since 1.1) 用来指定被trace的方法名, 可参考例子WebServiceTracker.java
o (since 1.2)可以通过注解的fqn boolean属性来表明是否要获取全限定方法名
- @com.sun.btrace.annotations.TargetInstance (since 1.1) 用来指定被trace方法内部被调用到的实例, 可参考例子AllCalls2.java
- @com.sun.btrace.annotations.TargetMethodOrField (since 1.1) 用来指定被trace方法内部被调用的方法名, 可参考例子AllCalls1.java 合 AllCalls2.java
o (since 1.2) 可通过注解的fqn boolean属性来表明是否要获取全限定方法名
未被注解的方法参数
未使用注解的方法参数一般都是用来做方法签名匹配用的, 他们一般和被trace方法中参数出现的顺序一致.
不过他们也可以与注解方法交错使用, 如果一个参数类型声明为*AnyType[]*, 则表明它按顺序"通吃"方法所有参数.
未注解方法需要与*Location*结合使用:
- Kind.ENTRY, Kind.RETURN- 被trace方法参数
- Kind.THROW - 抛异常
- Kind.ARRAY_SET, Kind.ARRAY_GET - 数组索引
- Kind.CATCH - 捕获异常
- Kind.FIELD_SET - 属性值
- Kind.LINE - 行号
- Kind.NEW - 类名
- Kind.ERROR - 抛异常
属性上的注解
- @com.sun.btrace.annotations.Export
该注解的静态属性主要用来与jvmstat计数器做关联. 使用该注解之后,
btrace程序就可以向jvmstat客户端(可以用来统计jvm堆中的内存使用量)暴露trace程序的执行次数,
具体可参考例子ThreadCounter.java
- @com.sun.btrace.annotations.Property
使用了该注解的trace脚本将作为MBean的一个属性, 一旦使用该注解, trace脚本就会创建一个MBean并向MBean服务器注册,
这样JMX客户端比如VisualVM, jconsole就可以看到这些BTrace MBean.
如果这些被注解的属性与被trace程序的属性关联, 那么就可以通过VisualVM 和jconsole来查看这些属性了.
具体可参考例子ThreadCounterBean.java 和 HistogramBean.java.
- @com.sun.btrace.annotations.TLS
用来将一个脚本变量与一个ThreadLocal变量关联. 因为ThreadLocal变量是跟线程相关的,
一般用来检查在同一个线程调用中是否执行到了被trace的方法. 具体可参考例子OnThrow.java 和
WebServiceTracker.java
类上的注解
- @com.sun.btrace.annotations.DTrace 用来指定btrace脚本与内置在其脚本中的D语言脚本关联, 具体参考例子DTraceInline.java.
- @com.sun.btrace.annotations.DTraceRef 用来指定btrace脚本与另一个D语言脚本文件关联. 具体参考例子DTraceRefDemo.java.
- @com.sun.btrace.annotations.BTrace 用来指定该java类为一个btrace脚本文件.
脚本举例如下
1.监控方法参数(数组)
-
import
static
com.sun.btrace.BTraceUtils.print;
-
import
static
com.sun.btrace.BTraceUtils.printArray;
-
import
static
com.sun.btrace.BTraceUtils.println;
-
import
static
com.sun.btrace.BTraceUtils.probeClass;
-
import
static
com.sun.btrace.BTraceUtils.probeMethod;
-
-
import
com.sun.btrace.annotations.BTrace;
-
import
com.sun.btrace.annotations.OnMethod;
-
-
@BTrace
-
public
class
PrintArgArray {
-
-
-
-
-
-
-
-
-
-
@OnMethod
(clazz =
"com.jerry.test.Test"
, method =
"mergeArray"
)
-
-
public
static
void
anyRead(Long[] arrayOne, Long[] arrayTwo) {
-
-
print(probeClass());
-
print(" ["
);
-
-
print(probeMethod());
-
println("]"
);
-
-
if
(arrayOne !=
null
) {
-
printArray(arrayOne);
-
} else
{
-
println("the arguments is null!"
);
-
}
-
-
if
(arrayTwo !=
null
) {
-
printArray(arrayTwo);
-
} else
{
-
println("the arguments is null!"
);
-
}
-
}
-
-
}
2.监控使用时间
-
import
static
com.sun.btrace.BTraceUtils.name;
-
import
static
com.sun.btrace.BTraceUtils.print;
-
import
static
com.sun.btrace.BTraceUtils.println;
-
import
static
com.sun.btrace.BTraceUtils.probeClass;
-
import
static
com.sun.btrace.BTraceUtils.probeMethod;
-
import
static
com.sun.btrace.BTraceUtils.str;
-
import
static
com.sun.btrace.BTraceUtils.strcat;
-
import
static
com.sun.btrace.BTraceUtils.timeMillis;
-
-
import
com.sun.btrace.annotations.BTrace;
-
import
com.sun.btrace.annotations.Kind;
-
import
com.sun.btrace.annotations.Location;
-
import
com.sun.btrace.annotations.OnMethod;
-
import
com.sun.btrace.annotations.TLS;
-
-
-
-
-
-
-
@BTrace
-
public
class
PrintTimes {
-
-
-
-
-
@TLS
-
private
static
long
startTime =
0
;
-
-
-
-
-
@OnMethod
(clazz =
"/com\\.jerry\\../"
, method =
"/.+/"
)
-
public
static
void
startMethod() {
-
startTime = timeMillis();
-
}
-
-
-
-
-
-
@SuppressWarnings
(
"deprecation"
)
-
@OnMethod
(clazz =
"/com\\.jerry\\../"
, method =
"/.+/"
, location =
@Location
(Kind.RETURN))
-
public
static
void
endMethod() {
-
-
print(strcat(strcat(name(probeClass()), "."
), probeMethod()));
-
print(" ["
);
-
print(strcat("Time taken : "
, str(timeMillis() - startTime)));
-
println("]"
);
-
}
-
}
3.监控内存
-
import
static
com.sun.btrace.BTraceUtils.*;
-
import
java.lang.management.MemoryUsage;
-
-
import
com.sun.btrace.annotations.BTrace;
-
import
com.sun.btrace.annotations.OnLowMemory;
-
-
-
-
-
-
-
@BTrace
-
public
class
PrintMemory {
-
-
-
-
-
@OnLowMemory
(pool =
"Tenured Gen"
, threshold =
6000000
)
-
public
static
void
printMem(MemoryUsage mu) {
-
print("MemoryUsage : "
);
-
println(mu);
-
print("FreeMem : "
);
-
println(freeMemory());
-
print("Heap:"
);
-
println(heapUsage());
-
print("Non-Heap:"
);
-
println(nonHeapUsage());
-
}
-
}
分享到:
相关推荐
3. **运行Btrace**:使用`btrace`命令启动Btrace,并指定要监控的Java进程ID以及脚本文件。 4. **查看结果**:Btrace 将在控制台输出监控数据,也可以选择将结果输出到文件或通过网络发送到其他工具进行进一步分析...
Java软件生产监控工具Btrace使用方法详解 Btrace是Sun公司推出的Java动态、安全追踪(监控)工具,可以在不需要重启的情况下监控系统运行情况,方便地获取程序运行时的数据信息,如方法参数、返回值、全局变量和...
在实际使用中,我们需要将BTrace工具部署到JVM上,通过指定应用的JAR或类路径来启动BTrace。执行BTrace命令时,需要提供监控脚本(如MorganTraceTest.java)和目标应用程序的PID。一旦BTrace运行起来,它就会开始...
2. **脚本编写**:BTrace使用一种简单的脚本语言,基于Groovy,开发者可以编写脚本来定义想要追踪的行为。例如,可以追踪方法调用、记录日志、计算性能指标等。 3. **安全机制**:BTrace有内置的安全策略,以防止不...
BTrace 使用Java Agent技术,通过字节码注入来跟踪和收集应用中的各种信息,如方法调用、对象创建等。在这个自我学习测试代码中,我们主要关注了如何监控`List`对象参数和自定义对象的参数。 1. **BTrace 的基本...
BTrace 使用 Java Agent 技术,它可以在不改变原有代码的情况下,利用 JVMTI(Java Virtual Machine Tool Interface)接口向运行中的 JVM 注入字节码。BTrace 提供了一种声明式的脚本语言,用户可以编写简单的脚本来...
4. **安全性**:由于 Btrace 使用 Java 代理机制,只有具备权限的用户才能启用监控,增加了系统的安全性。 5. **可扩展性**:Btrace 支持与其他监控工具集成,例如日志记录框架、告警系统等,可以轻松地扩展其功能。...
2. **BTrace Scripts**:BTrace使用一种简单的脚本语言,让开发者能够编写诊断脚本。这些脚本定义了要在目标应用中执行的操作,如记录方法调用、计时器、内存使用情况等。BTrace脚本语言具有丰富的内置函数和变量,...
### BTrace使用步骤 1. **安装与配置**:下载BTrace并将其添加到系统路径,确保JDK也在系统路径中。 2. **编写BScript**:使用BTrace特有的BScript语言编写探查脚本,定义需要追踪的行为和数据。 3. **创建Java ...
2. **安全性**:BTrace使用JDK的动态代理机制,确保只在安全的点插入探查代码,避免引发运行时错误或性能下降。 3. **实时性能分析**:通过BTrace,你可以实时查看方法调用的时间、对象创建频率、内存分配情况等,...
BTrace使用这个API获取`Instrumentation`实例,进而利用ASM生成的字节码对目标类进行改造。例如,BTrace可以通过`retransformClasses`方法在运行时对已经加载的类进行重新转换,添加监控代码。 4. **Java Compiler ...
1. **编写脚本**:Btrace使用一种基于Groovy的脚本语言,你可以通过学习官方提供的samples来快速上手。这些脚本通常包含探查点(probe),在特定的代码行或方法执行时被触发。 2. **查找Java进程**:使用`jps`命令...
BCEL (Byte Code Engineering Library) 是一个用于处理 Java 字节码的库,BTrace 在注入探针时可能使用了 BCEL 来生成和操作字节码。BCEL 提供了工具来解析、创建、修改和打印 Java 类文件。 7. **使用场景**: -...
- **自定义脚本**:BTrace使用一种基于Java的脚本语言,允许开发者编写简单的脚本来定义想要追踪的行为,例如记录特定方法的执行时间、参数和返回值。 - **安全无侵入**:BTrace遵循最小权限原则,仅对指定的方法...
**BTrace监控远程服务器使用实例** BTrace 是一个强大的、安全的、动态的Java应用程序诊断工具,它允许开发者在运行时对Java应用进行细粒度的监控和性能分析。BTrace利用了Java的动态代理机制(Java Agent)和ASM...
由于BTrace使用的是字节码级别的修改,因此它能够在运行时实现对Java应用程序的监控,而无需重启服务。 **安装配置和注意事项** 安装BTrace通常只需下载官方仓库(https://github.com/btraceio/btrace)提供的版本...
7. **使用BTrace**:现在你可以使用BTrace进行性能调优了。选择你的目标Java进程,点击“BTrace”选项,编写或导入BTrace脚本,然后应用到进程中。BTrace脚本可以让你在运行时动态地添加代码,以观察类的方法调用、...
【标题】:“btrace支持jdk1.7 linux下使用” 【描述】:“btrace支持jdk1.7 linux下使用 非常好用哦 呵呵呵呵” 【知识点详解】 BTrace(全称:Bytecode Tracing for Java)是一款强大的动态追踪工具,专为Java...