package com.dianping.data; import java.util.Random; /** * @author star.li * @date 16/4/14. */ 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); } } }
package com.dianping.data; /** * @author star.li * @date 16/4/14. */ 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; } }
4.有沒有人調用CaseObject中的特定某行代碼?
1.監控函數的參數、返回值、靜態類成員變量
import com.sun.btrace.annotations.*; import static com.sun.btrace.BTraceUtils.*; import com.dianping.data.*; @BTrace public class TraceMethodArgsAndReturn { @OnMethod( clazz="com.dianping.data.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("com.dianping.data.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="com.dianping.data.CaseObject", method="execute" ) public static void traceExecuteBegin(){ beginTime=timeMillis(); } @OnMethod( clazz="com.dianping.data.CaseObject", method="execute", location=@Location(Kind.RETURN) ) public static void traceExecute(){ 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="com.dianping.data.CaseObject", method="execute" ) public static void traceExecute(){ println("who call CaseObject.execute :"); jstack(); } }
import static com.sun.btrace.BTraceUtils.*; import com.sun.btrace.annotations.*; @BTrace public class TraceMethodLine{ @OnMethod( clazz="com.dianping.data.CaseObject", location=@Location(value=Kind.LINE,line=11) ) public static void traceExecute(@ProbeClassName String pcn,@ProbeMethodName String pmn,int line){ println(strcat(strcat(strcat(strcat(strcat("call ",pcn),"."),pmn),"at line:"),str(line))); } }
本文的例子參考bluedavy(畢玄/林昊)的文章:BTrace使用簡介:http://bluedavy.me/?p=185 其他幾篇可以看看的文章:
需要注意的一點是,btrace監控退出後,修改過的class不會被恢復,你的所有的監控代碼依然一直在運行。每次執行你的監控代碼之前會先進行一個判斷,判斷當前是否處於監控中。你的客戶端發起了exit指令後,該方法判斷false,直接return。所以btrace使用退出後會讓你的代碼多走了一個方法調用+一個對象屬性判斷.
使用JVisualVM的BTrace插件
1.安裝BTrace插件
打開VisualVM的工具—插件,在可用插件列表中選擇BTrace Workbench進行安裝
2.選擇java應用,右鍵選擇Trace application...即可打卡BTrace界面
3.在打開的BTrace界面中編寫監控腳本代碼,並執行(可根據需要調整classpath)