由于项目用到了Btrace,因此这里先简单的谈一下Btrace的简单的应用,以后用到别的知识的时候在记录。
1.Btrace的限制
- 不能创建新的object
- 不能创建新的arrays
- 不能抛出异常
- 不能捕获异常
- 不能调用实例方法及静态方法(BTraceUtils中的方法除外)
- 不能将目标程序和对象赋值给BTrace的实例和静态field
- 不能定义外部, 内部, 匿名, 本地类
- 不能有同步块和方法
- 不能有循环
- 不能实现接口, 不能扩展类
- 不能使用assert语句, 不能使用class字面值
// import all BTrace annotations
import com.sun.btrace.annotations.*;
// import statics from BTraceUtils class
import static com.sun.btrace.BTraceUtils.*;
// @BTrace annotation tells that this is a BTrace program
@BTrace
class HelloWorld {
// @OnMethod annotation tells where to probe.
// In this example, we are interested in entry
// into the Thread.start() method.
@OnMethod(
clazz="java.lang.Thread",
method="start"
)
void func() {
sharedMethod(msg);
}
void sharedMethod(String msg) {
// println is defined in BTraceUtils
println(msg);
}
}
类开始之前要加上@Btrace。
@OnMethod指出了要监视哪个类的哪个方法(clazz指出那个类,method指出那个方法,location应该是指出在哪里执行下面的代码。)
3.参数上注解
@Self 指被监视的方法的this
@Return指被监视的方法的返回值
@ProbeClassName指被监视的类名 同理ProbeMethodName
@TargetInstance 指定被trace方法内部被调用到的实例
@TargetMethodOrField 指定被trace方法内部被调用的方法名
看到一个方法参数为AnyType,表示被监视方法的参数,若为AnyType[],表示被监视方法的所有参数
Btrace官网:https://kenai.com/projects/btrace/
下面是网上看的常用的几个例子,先看代码:
import java.util.Random;
public class Case1{
public static void main(String[] args) throws Exception{
Random random=new Random();
CaseObject object=new CaseObject();
boolean result=true;
while(result){
result=object.execute(random.nextInt(1000));
Thread.sleep(1000);
}
}
}
public class CaseObject{
private static int sleepTotalTime=0;
public boolean execute(int sleepTime) throws Exception{
System.out.println("sleep: "+sleepTime);
sleepTotalTime+=sleepTime;
Thread.sleep(sleepTime);
return true;
}
}
1.调用此方法时传入的参数是多少,返回值是什么?
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
@BTrace public class TraceMethodArgsAndReturn{
@OnMethod(
clazz="CaseObject",
method="execute",
location=@Location(Kind.RETURN)
)
public static void traceExecute(@Self CaseObject instance,int sleepTime,@Return boolean result){
println("call CaseObject.execute");
println(strcat("sleepTime is:",str(sleepTime)));
println(strcat("sleepTotalTime is:",str(get(field("CaseObject","sleepTotalTime"),instance))));
println(strcat("return value is:",str(result)));
}
}
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
@BTrace public class TraceMethodExecuteTime{
@TLS static long beginTime;
@OnMethod(
clazz="CaseObject",
method="execute"
)
public static void traceExecuteBegin(){
beginTime=timeMillis();
}
@OnMethod(
clazz="CaseObject",
method="execute",
location=@Location(Kind.RETURN)
)
public static void traceExecute(int sleepTime,@Return boolean result){
println(strcat(strcat("CaseObject.execute time is:",str(timeMillis()-beginTime)),"ms"));
}
}
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
@BTrace public class TraceMethodCallee{
@OnMethod(
clazz="CaseObject",
method="execute"
)
public static void traceExecute(){
println("who call CaseObject.execute :");
jstack();
}
}
4.有没有人调用CaseObject中哪一行代码?
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
@BTrace
public class TraceMethodLine{
@OnMethod(
clazz="CaseObject",
location=@Location(value=Kind.LINE,line=5)
)
public static void traceExecute(@ProbeClassName String pcn,@ProbeMethodName String pmn,int line){
println(strcat(strcat(strcat("call ",pcn),"."),pmn));
}
}
其中的函数在util包中。