本文主要介紹BTrace的使用
1.簡單使用Demo
》新建一個工程,目錄如下所示:
》》運行一個app程序。源碼如下:
import org.apache.commons.lang3.StringUtils;
import java.util.Random;
/**
* Created by dell on 2016/12/18.
*/
public class BtraceTest
{
public static void main(String[] args)
{
String[] strs = {"", "1", "2"};
Random random = new Random();
String str;
while (true)
{
str = getStr(strs, random);
if (StringUtils.isEmpty(str))
{
System.out.println("It is impty.");
}
else
{
System.out.println("It is " + str);
}
try
{
Thread.sleep(5000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
private static String getStr(String[] strs, Random random)
{
int index = random.nextInt(strs.length);
return strs[index];
}
}
》》》Btrace腳本(Demo1.java),源碼如下:
import com.sun.btrace.BTraceUtils;
import com.sun.btrace.annotations.*;
import java.util.Random;
@BTrace
public class Demo1
{
@OnMethod(clazz = "BtraceTest",method = "getStr", location = @Location(Kind.RETURN))
public static void m2(String[] strs, Random random, @Return String str)
{
BTraceUtils.println(str);
BTraceUtils.println();
BTraceUtils.println();
}
}
》》》》將腳本拷貝到${BTRACE_HOME}/samples下面,修改該文件的權限爲可執行(和app程序運行的用戶爲同一個用戶)。
》》》》》運行app程序,在相同的用戶下運行Btrace腳本,格式爲${BTRACE_HOME}/bin/btrace app的pid Btrace腳本(Demo1.java),本實例使用如下命令執行:
zm@Inspiron:~/app/bin$ ./btrace `ps -ef |grep Btrace|grep -v grep|awk '{print $2}'` ../samples/Demo1.java
》》》》》》可以觀察該函數中的返回值。
2.使用自定義的shell腳本運行Btrace腳本,來跟蹤自己的類中的數據。
一般情況下,app程序引用三方jar包(非btrace jar包),並且跟蹤的類時在三方包中,這時候就需要自己重新寫一個shell腳本(或着修改已有的腳本)來運行btrace腳本了。
舉例:跟蹤Apache jar包中的StringUtils.isempty(CharSequence chars)方法。app程序和上例中的一致。btrace腳本源碼(Demo.java)如下:
import com.sun.btrace.BTraceUtils;
import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.Kind;
import com.sun.btrace.annotations.Location;
import com.sun.btrace.annotations.OnMethod;
@BTrace
public class Demo
{
@OnMethod(clazz = "org.apache.commons.lang3.StringUtils", method = "isEmpty", location = @Location(Kind.ENTRY))
public static void m1(java.lang.CharSequence chars)
{
BTraceUtils.println(chars);
BTraceUtils.println("");
BTraceUtils.println("");
}
}
運行該btrace腳本使用的shell腳本(run.sh)如下:
#! /bin/sh
CUR_PATH=`pwd`
BTRACE_HOME=$(dirname "${CUR_PATH}")
#get class_path of app
for s in $(ls ${BTRACE_HOME}/build/* |grep ".jar")
do
CLASS_PATH_1=`echo $s`:${CLASS_PATH_1}
done
if [ -f "${BTRACE_HOME}/build/btrace-client.jar" ] ; then
if [ "${JAVA_HOME}" != "" ]; then
TOOLS_JAR="${JAVA_HOME}/lib/tools.jar"
${JAVA_HOME}/bin/java -cp ${CLASS_PATH_1}${TOOLS_JAR} com.sun.btrace.client.Main $*
else
echo "Please set JAVA_HOME before running this script"
exit 1
fi
else
echo "Please set BTRACE_HOME before running this script"
exit 1
fi
》》》可以將Demo.java 和 run.sh放在${BTRACE_HOME}/samples,修改完權限以後,直接在app程序運行的用戶下執行${BTRACE_HOME}/samples app的pid Demo.java
3.定時查看內存的腳本(每4秒打印一次),源碼:
import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.OnTimer;
import static com.sun.btrace.BTraceUtils.*;
@BTrace
public class TraceMemory
{
//heapUsage()/nonHeapUsage() – 打印堆/非堆內存信息,包括init、used、commit、max
@OnTimer(4000)
public static void printM()
{
//打印內存信息
println("heap:");
println(heapUsage());
println("no-heap:");
println(nonHeapUsage());
}
}