国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

Java運行時(shí)如何使用追蹤工具BTrace

發(fā)布時(shí)間:2021-09-27 17:50 來(lái)源:億速云 閱讀:0 作者:柒染 欄目: 開(kāi)發(fā)技術(shù)

這期內容當中小編將會(huì )給大家帶來(lái)有關(guān)Java運行時(shí)如何使用追蹤工具BTrace,文章內容豐富且以專(zhuān)業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

1. BTrace是什么?

Btrace是由sundararajan在2009年6月開(kāi)發(fā)的一個(gè)開(kāi)源項目,是一種動(dòng)態(tài)跟蹤分析一個(gè)運行中的Java應用程序的工具。 BTrace是一個(gè)為Java平臺開(kāi)發(fā)的安全、動(dòng)態(tài)的追蹤工具。BTrace動(dòng)態(tài)地向目標應用程序的字節碼注入追蹤代碼(字節碼追蹤),這些追蹤字節碼追蹤代碼使用Java語(yǔ)言表達,也就是BTrace的腳本。

2. BTrace約束

為了保證追蹤動(dòng)作是“只讀”的(也就是這些動(dòng)作不可以修改被追蹤程序的狀態(tài))和有限度的(比如在固定時(shí)間里結束)。一個(gè)BTrace程序只允許完成一些指定的動(dòng)作。下面是BTrace一些不可以完成的事情:

  • 不能創(chuàng )建新的對象

  • 不能創(chuàng )建新的數組

  • 不能拋出異常

  • 不能捕獲異常

  • 不能進(jìn)行任何的實(shí)例函數或者靜態(tài)函數 – 只有com.sun.btrace.BTraceUtils類(lèi)中的靜態(tài)函數或者BTrace程序自己聲明的函數才可以被BTrace調用

  • 不可以在目標程序的類(lèi),或者對象的靜態(tài)或者實(shí)例級別的field進(jìn)行賦值。但是,BTrace自身的類(lèi)是可以給它的靜態(tài)field進(jìn)行賦值的

  • 不能有outer,inner,嵌套的或者本地類(lèi)。

  • 不能有同步代碼塊或者同步的函數

  • 不能有循環(huán)語(yǔ)句(for,while, do..while)

  • 不能繼承其它類(lèi)(父類(lèi)只能是java.lang.Object)

  • 不能實(shí)現接口

  • 不能包含斷言(assert)語(yǔ)句

  • 不能使用類(lèi)字面值

這上面的種種限制可以通過(guò)一個(gè)配置改變:unsafe=true,在使用BTrace注解時(shí)修改該屬性的默認值(false)為true,即@BTrace(unsafe=true);也可以啟動(dòng)選項中顯式聲明-Dcom.sun.btrace.unsafe=true(響應也有-u參數);現在你可以為所欲為了。BUT,這樣做之前最好考慮好風(fēng)險并再三檢查腳本,請斟酌使用!

3. BTrace安裝

btrace git下載地址 ,下載release版本下來(lái)直接解壓就可以使用。

3.1 基本語(yǔ)法
btrace <pid> <btrace-script>腳本

btrace命令行工具運行命令如下:

btrace <options> <pid> <btrace source or .class file> <btrace arguments>
常用選項:
[-I <include-path>] [-p <port>] [-cp <classpath>]

參數說(shuō)明:

where possible options include:
  --version             Show the version
  -v                    Run in verbose mode
  -o <file>             The path to store the probe output (will disable showing the output in console)
  -u                    Run in trusted mode
  -d <path>             Dump the instrumented classes to the specified path
  -pd <path>            The search path for the probe XML descriptors
  -classpath <path>     Specify where to find user class files and annotation processors
  -cp <path>            Specify where to find user class files and annotation processors
  -I <path>             Specify where to find include files
  -p <port>             Specify port to which the btrace agent listens for clients
  -statsd <host[:port]> Specify the statsd server, if any
  • include-path : 是一些用來(lái)查找頭文件的目錄。BTrace包含一個(gè)簡(jiǎn)單的預處理,支持# define,# + include和條件編譯。它不像一個(gè)完整的C / c++預處理器–而是一個(gè)有用的子集。詳見(jiàn)demo代碼“ThreadBean.java”,如果沒(méi)有顯式的聲明選項-I,Btrace跳過(guò)預處理程序調用步驟。

  • port: BTrace代理程序所偵聽(tīng)的端口,這是可選的選項。默認是2020

  • classpath: 是一些用來(lái)查找jar文件的目錄。默認是當前目錄”.”

  • pid:是要追蹤目標程序id

  • btrace-script: 就是追蹤程序本身。如果這是個(gè)java文件,那么提交前會(huì )進(jìn)行編譯。否則,它被認為已預編譯(即它必須是一個(gè)類(lèi))并提交

  • arguments: 這是傳遞給BTrace程序的參數。BTrace程序可以通過(guò)內置的符號來(lái)引用這些參數,length是這些參數的個(gè)數。

在samples目錄下有很多示例,并且有的跟蹤很有用可直接使用.

4. BTrace的注解

4.1 方法注解
  • @com.sun.btrace.annotations.OnMethod 該注解可用來(lái)指定目標類(lèi),目標方法,以及目標方法里的“位置”。加了該注解后的操作方法會(huì )在對應的方法運行到指定的“位置”時(shí)被執行。該注解中,目標類(lèi)用“clazz”屬性來(lái)指定,而目標方法用“method”屬性來(lái)指定?!眂lazz”可以是類(lèi)的全路徑(比如java.awt.Component或者用兩個(gè)反斜杠中間的正則表達式,參考例子NewComponent.javaClassload.java來(lái)看它們的用法,正則表達式可以匹配0個(gè)或多個(gè)目標類(lèi),這個(gè)時(shí)候多個(gè)類(lèi)都會(huì )被進(jìn)行動(dòng)態(tài)指令更換。如/java.awt.+/匹配java.awt包下的所有類(lèi))。方法名也可以用這樣的正則表達式 來(lái)匹配零個(gè)或者多個(gè)多個(gè)方法。參考例子MultiClass.java來(lái)查看用法。還有一種方法來(lái)指定追蹤類(lèi)和函數。被追蹤的類(lèi)和函數可以用注解來(lái)指定。比如,如果”clazz”屬性是@javax.jws.Webservice.那么BTrace會(huì )會(huì )把所有注解是這個(gè)的函數都進(jìn)行動(dòng)態(tài)指令更換。類(lèi)似地,方法級別的注解也可以用來(lái)執行方法。參看例子WebServiceTracker.java來(lái)了解如何使用??梢园颜齽t表達式和注解放在一起用,比如@/com.acme..+/可以匹配任何類(lèi),只要這個(gè)類(lèi)的注解能跟那段正則表達式匹配即可??梢酝ㄟ^(guò)指定父類(lèi)來(lái)匹配多個(gè)類(lèi)名,比如+java.lang.Runnable就可以匹配所有實(shí)現了java.lang.Runnable這個(gè)接口的類(lèi)。參考例子SubtypeTracer.java來(lái)看它的用法。

  • @com.sun.btrace.annotations.OnTimer 該注解可以用來(lái)執行那些需要周期性(間隔是毫秒)的追蹤操作。參考Histogram.java來(lái)看它的用法。

  • @com.sun.btrace.annotations.OnError 該注解可以用來(lái)指定當任何異常拋出時(shí)需要執行的操作。被該注解修飾后的BTrace函數會(huì )在同一個(gè)BTrace類(lèi)的其他操作方法拋出異常時(shí)執行。

  • @com.sun.btrace.annotations.OnExit 該注解用來(lái)執行黨BTrace代碼調用了exit(int)結束追蹤會(huì )話(huà)后需要執行的操作。參考例子ProbeExit.java來(lái)了解如何使用。

  • @com.sun.btrace.annotations.OnEvent 該注解用來(lái)追蹤函數與”外部”的事件關(guān)聯(lián)起來(lái)。當BTrace客戶(hù)端發(fā)送了一個(gè)“事件”后,該注解里的操作就會(huì )被執行??蛻?hù)端發(fā)送的事件可能是由用戶(hù)觸發(fā)的(比如按下Ctrl-C)。事件的名字是個(gè)字符串,這樣追蹤操作就只會(huì )在對應的事件觸發(fā)后被執行。到目標為止,BTrace命令行客戶(hù)端會(huì )在用戶(hù)按下Ctrl-C后發(fā)送事件,參考例子HistoOnEvent.java來(lái)了解用法。

  • @com.sun.btrace.annotations.OnLowMemory 該注解可以用來(lái)追蹤特定內存閾值被用光的事件。參看例子MemAlerter.java了解用法。

  • @com.sun.btrace.annotations.OnProbe 該注解可以用來(lái)避免使用BTrace腳本的內部類(lèi)。@OnProbe探測點(diǎn)被映射到一個(gè)或多個(gè)@OnMethod上。目前這個(gè)映射是通過(guò)一個(gè)XML探測描述文件類(lèi)指定的(這個(gè)文件會(huì )被BTrace代理所使用)。參考例子SocketTracker1.java和對應的描述文件java.net.socket.xml.當運行這個(gè)例子時(shí),xml文件需要放在目標JVM所有運行的目錄下(或者修改btracer.bat中的probeDescPath選項來(lái)指向任意的xml文件)。

  • @com.sun.btrace.annotations.Location:該注解在一個(gè)traced/probed方法中指定一個(gè)特定的“位置”

  • @com.sun.btrace.annotations.Simpled:標記@OnMethod注解處理器采樣。采樣處理程序時(shí)并不是所有的事件將被追蹤,只有一個(gè)統計樣品與給定的意思。在默認情況下使用一種自適應采樣。BTrace將增加或減少樣品之間的調用數量保持平均時(shí)間窗口,因此減少整體的開(kāi)銷(xiāo)。

4.2 參數相關(guān)的注解
  • @com.sun.btrace.annotations.Self:該注解把一個(gè)參數標識為保留了目標函數所指向的this的值。參考例子AWTEventTracer.javaAllCalls1.java.

  • @com.sun.btrace.annotations.Return:該注解說(shuō)明這個(gè)參數保存目標函數的返回值。參考例子Classload.java

  • @com.sun.btrace.annotations.ProbeClassName:所修飾的參數保留了探測類(lèi)的類(lèi)名 。參看AllMethods.java(有多個(gè)探測類(lèi))

  • @com.sun.btrace.annotations.ProbeMethodName:所修飾的參數保留了探測函數的函數名。參考WebServiceTracker.java(多個(gè)探測函數)

  • @com.sun.btrace.annotations.TargetInstance:修飾的參數保留了被調用的實(shí)例。參考例子AllCall2.java.

  • @com.sun.btrace.annotations.TargetMethodOrField:該注解修飾的參數保存了調用的函數名。參考AllCalls1.javaAllCall2.java

  • @com.sun.btrace.annotations.Duration:探測方法參數標記為持續時(shí)間值的接收者,即目標方法執行的時(shí)間,單位納秒。只是用帶Location屬性的@OnMethod,并且需要配合Kind.ERROR或者Kind.RETURN使用

4.3 無(wú)注解的參數

沒(méi)有注解的BTrace探測函數參數是用來(lái)作簽名匹配的,因為他們必須必須在固定的位置上出現。然而,它們可以和其他的注解的參數進(jìn)行交換。如果一個(gè)參數的類(lèi)型是_AnyType[]_,它就會(huì )“吃”掉所所有剩下的參數。沒(méi)有注解的參數的具體含義與他們所在的位置有關(guān):

4.4 字段相關(guān)的注解
  • @com.sun.btrace.annotations.Export BTrace字段使用該注解來(lái)說(shuō)明它已經(jīng)被映射到一個(gè)jvmstat計數器上。使用該注解,BTrace程序可以把追蹤計數器暴露給外部的jvmstat客戶(hù)端(比如jstat)。參考例子ThreadCounter.java

  • @com.sun.btrace.annotations.Property 該注解可以把一個(gè)字段標識為一個(gè)MBean屬性。如果一個(gè)BTrace類(lèi)至少有一個(gè)靜態(tài)的字段使用了該注解。那么一個(gè)MBean就會(huì )被創(chuàng )建并且注冊到平臺MBean上。JMX客戶(hù)端比如VisualVM,jconsole可以訪(fǎng)問(wèn)這個(gè)字段來(lái)查看BTrace的MBean。在把BTrace附加到目標程序上后,你可以把VisualVM或者jconsole也附加到同一個(gè)目標程序上來(lái)查看剛創(chuàng )建好的MBean屬性。通過(guò)VisualVM或者jconsole,你可以通過(guò)MBeans tab頁(yè)來(lái)查看BTrace相關(guān)的域,然后查看它們的值。參考例子ThreadCounterBean.javaHistogramBean.java來(lái)了解用法

  • @com.sun.btrace.annotations.TLS BTrace字段使用該注解來(lái)說(shuō)明它自己是一個(gè)線(xiàn)程本地字段(thread local field).注意你只能在@OnMethod注解后的函數里訪(fǎng)問(wèn)這樣的字段。每個(gè)Java線(xiàn)程都有一個(gè)這個(gè)字段的拷貝。為了讓這樣的方式能夠工作,這個(gè)字段的類(lèi)型只能是immutable(比如原始類(lèi)型) 或者是cloneable (實(shí)現了Cloneable接口并且覆蓋了clone()函數)的。這些線(xiàn)程本地字段可以被BTrace程序用來(lái)識別它是否在同一個(gè)線(xiàn)程里執行了多個(gè)探測操作。參考例子OnThrow.javaWebServiceTracker.java

4.5 類(lèi)相關(guān)的注解
  • @com.sun.btrace.annotations.DTrace該注解用來(lái)把一小段D腳本(嵌在BTrace 的java類(lèi)中)和BTrace程序關(guān)聯(lián)起來(lái)。參考例子DTraceInline.java

  • @com.sun.btrace.annotations.DTraceRef 和上個(gè)注解一樣,不同的是D腳本是在獨立的文件中,不是嵌在java類(lèi)中。

  • @com.sun.btrace.annotations.BTrace必須使用該注解來(lái)指定一個(gè)Java類(lèi)是BTrace程序。BTrace編譯器會(huì )強制查找該注解,BTrace代理也會(huì )檢查這個(gè)是否有該注解。如果沒(méi)有,則提示錯誤,并且不會(huì )執行。

5. 使用示例

5.1 準備示例代碼
package com.gitee.funcy.jtools.btrace;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

/**
 * 該程序周期性地進(jìn)行網(wǎng)絡(luò )讀取操作
 *
 * @author chengyan
 * @date 2019-11-03 10:41 下午
 */
public class HoldNetTask implements Runnable{

    public void visitWeb(String strUrl) {
        URL url = null;
        URLConnection urlconn = null;
        InputStream is = null;
        try {
            url = new URL(strUrl);
            urlconn = url.openConnection();
            is = urlconn.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
            StringBuffer bs = new StringBuffer();
            String l = null;
            while((l = bufferedReader.readLine()) != null) {
                bs.append(l).append("\r\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(is != null) {
                try {
                    is.close();
                } catch (Exception e) {

                }
            }
        }
    }

    @Override
    public void run() {
        while(true) {
            visitWeb("http://www.sina.com.cn");
        }
    }

    public static void main(String[] args) {
        new Thread(new HoldNetTask()).start();
    }

}
5.2 導入相關(guān)jar包
1. 直接導入jar包

BTrace對應的java包在Btrace release文件的build目錄下,一共有三個(gè)jar包:

btrace-agent.jar
btrace-boot.jar
btrace-client.jar
2. 使用maven引入jar包

也可使用maven引入依賴(lài)包,在pom文件中添加以下內容:

<properties>
	...省略其他
	<btrace.version>1.3.11.3</btrace.version>
</properties>

<dependencies>
	...省略其他
	<dependency>
		<groupId>com.sun.tools.btrace</groupId>
		<artifactId>btrace-agent</artifactId>
		<version>${btrace.version}</version>
	</dependency>
	<dependency>
		<groupId>com.sun.tools.btrace</groupId>
		<artifactId>btrace-boot</artifactId>
		<version>${btrace.version}</version>
	</dependency>
	<dependency>
		<groupId>com.sun.tools.btrace</groupId>
		<artifactId>btrace-client</artifactId>
		<version>${btrace.version}</version>
	</dependency>
</dependencies>

<repositories>
	<repository>
		<id>btrace-repo</id>
		<name>btrace-repo</name>
		<url>https://dl.bintray.com/btraceio/maven/</url>
		<releases>
			<enabled>true</enabled>
		</releases>
		<snapshots>
			<enabled>false</enabled>
		</snapshots>
	</repository>
</repositories>

需要注意的是,maven中央倉庫中可能沒(méi)有btrace的最新版本,為此需要配置額外的倉庫。

5.3 監控函數的耗時(shí)

使用BTrace腳本可以通過(guò)正則表達式指定監控特定類(lèi)的特定方法的耗時(shí),以下代碼將監控所有類(lèi)中名為visitWeb()的函數的執行時(shí)間。

package com.gitee.funcy.jtools.btrace;

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.ProbeClassName;
import com.sun.btrace.annotations.ProbeMethodName;
import com.sun.btrace.annotations.TLS;

import static com.sun.btrace.BTraceUtils.*;

/**
 * {這里添加描述}
 *
 * @author chengyan
 * @date 2019-11-03 12:13 上午
 */
@BTrace
public class PrintTimes {

    @TLS
    private static long startTime = 0;

    /**
     * 方法調用開(kāi)始
     * clazz = "/.+/" : 監控做任意類(lèi)
     * method="/visitWeb/":監控visitWeb方法
     */
    @OnMethod(clazz = "/.+/", method="/visitWeb/")
    public static void startMethod() {
        startTime = timeMillis();
    }

    @OnMethod(clazz = "/.+/", method="/visitWeb/", location=@Location(Kind.RETURN))
    public static void endMethod(@ProbeClassName String pcm, @ProbeMethodName String pmn) {
        println(pcm + "." + pmn + " [Time taken: " + str(timeMillis() - startTime) + "ms]");
    }
}

運行結果:

$ btrace 42188 PrintTimes.java
com.gitee.funcy.jtools.btrace.HoldNetTask.visitWeb [Time taken: 55ms]
com.gitee.funcy.jtools.btrace.HoldNetTask.visitWeb [Time taken: 50ms]
com.gitee.funcy.jtools.btrace.HoldNetTask.visitWeb [Time taken: 52ms]
com.gitee.funcy.jtools.btrace.HoldNetTask.visitWeb [Time taken: 49ms]
com.gitee.funcy.jtools.btrace.HoldNetTask.visitWeb [Time taken: 54ms]
com.gitee.funcy.jtools.btrace.HoldNetTask.visitWeb [Time taken: 54ms]
5.4 監控函數參數

除了執行時(shí)間,BTrace也可輸出函數的參數:

package com.gitee.funcy.jtools.btrace;

import com.sun.btrace.AnyType;
import com.sun.btrace.BTraceUtils;
import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.ProbeClassName;
import com.sun.btrace.annotations.ProbeMethodName;

/**
 * {這里添加描述}
 *
 * @author chengyan
 * @date 2019-11-03 10:43 下午
 */
@BTrace
public class PrintArgs {
    @OnMethod(clazz = "/.*HoldNetTask/",method = "/visitWeb/")
    public static void anyWriteFile(@ProbeClassName String pcn, @ProbeMethodName String pmn, AnyType[] args) {
        BTraceUtils.print(pcn + "-" + pmn);
        BTraceUtils.printArray(args);
    }
}

運行結果:

$ btrace 46877 PrintArgs.java
com.gitee.funcy.jtools.btrace.HoldNetTask-visitWeb[http://www.sina.com.cn, ]
com.gitee.funcy.jtools.btrace.HoldNetTask-visitWeb[http://www.sina.com.cn, ]
com.gitee.funcy.jtools.btrace.HoldNetTask-visitWeb[http://www.sina.com.cn, ]
com.gitee.funcy.jtools.btrace.HoldNetTask-visitWeb[http://www.sina.com.cn, ]
com.gitee.funcy.jtools.btrace.HoldNetTask-visitWeb[http://www.sina.com.cn, ]
com.gitee.funcy.jtools.btrace.HoldNetTask-visitWeb[http://www.sina.com.cn, ]
5.5 取得做任意行代碼信息

通過(guò)BTrace腳本@Location注解,可以指定程序運行到某一行代碼時(shí),觸發(fā)某一行為。下例顯示了通過(guò)BTrace腳本獲取HoldNetTask 類(lèi)第27行代碼的信息(當目標程序運行到第27行時(shí),觸發(fā)BTrace腳本)。

package com.gitee.funcy.jtools.btrace;

import static com.sun.btrace.BTraceUtils.*;

import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.Location;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.Kind;
import com.sun.btrace.annotations.ProbeClassName;
import com.sun.btrace.annotations.ProbeMethodName;

/**
 * {這里添加描述}
 *
 * @author chengyan
 * @date 2019-11-04 10:02 下午
 */
@BTrace
public class AllLines {

    @OnMethod(clazz = "/.*HoldNetTask/", location = @Location(value = Kind.LINE, line = 27))
    public static void online(@ProbeClassName String pcn, @ProbeMethodName String pmn, int line) {
        println(pcn + "." + pmn + ":" + line);
    }
}

運行結果:

$ btrace 46877 AllLines.java
com.gitee.funcy.jtools.btrace.HoldNetTask.visitWeb:27
com.gitee.funcy.jtools.btrace.HoldNetTask.visitWeb:27
com.gitee.funcy.jtools.btrace.HoldNetTask.visitWeb:27
com.gitee.funcy.jtools.btrace.HoldNetTask.visitWeb:27
com.gitee.funcy.jtools.btrace.HoldNetTask.visitWeb:27
com.gitee.funcy.jtools.btrace.HoldNetTask.visitWeb:27

由腳本輸出可以看到,BTrace正確識別出HoldNetTask類(lèi)的第27行代碼,正處于visitWeb() 函數的運行區間中。若將 @Location 中line的值設置為-1,則BTrace腳本將在每一行觸發(fā)。

5.6 定時(shí)觸發(fā)

BTrace腳本支持定時(shí)觸發(fā)??梢灾芷谛缘貓绦心骋恍袨?,獲取系統信息。下例使用@OnTimer 標記制定兩個(gè)周期性任務(wù),分別為每秒運行一次和每3秒運行一次。

package com.gitee.funcy.jtools.btrace;

import com.sun.btrace.BTraceUtils;
import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.OnTimer;

import static com.sun.btrace.BTraceUtils.jstackAll;
import static com.sun.btrace.BTraceUtils.println;

/**
 * {這里添加描述}
 *
 * @author chengyan
 * @date 2019-11-04 10:11 下午
 */
@BTrace
public class Timers {

    @OnTimer(1000)
    public static void getUpTime() {
        println(BTraceUtils.Strings.strcat("1000 msec:", BTraceUtils.Strings.str(BTraceUtils.Sys.VM.vmUptime())));
    }

    @OnTimer(3000)
    public static void getStack() {
        jstackAll();
    }
}

運行結果:

$ btrace 46969 Timers.java
1000 msec:27654
1000 msec:28647
Thread[Attach Listener,9,system]


Thread[Signal Dispatcher,9,system]


Thread[Thread-1,9,system]

	java.net.PlainSocketImpl.socketAccept(Native Method)
	java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
	java.net.ServerSocket.implAccept(ServerSocket.java:545)
	java.net.ServerSocket.accept(ServerSocket.java:513)
	com.sun.btrace.agent.Main.startServer(Main.java:668)
	com.sun.btrace.agent.Main.access$000(Main.java:63)
	com.sun.btrace.agent.Main$2.run(Main.java:128)
	java.lang.Thread.run(Thread.java:748)

getUpTime()方法中,指定了一個(gè)每秒運行一次的任務(wù),并打印虛擬機的啟動(dòng)時(shí)間。在getStack()方法中,指定了一個(gè)每3秒運行一次的任務(wù),每次都將導出系統的線(xiàn)程快照。

5.7 獲取類(lèi)的屬性

在程序運行過(guò)程中,BTrace可以在指定的位置獲得對象實(shí)例的字段信息。比如,在本實(shí)例中,可以在調用URL.openConnection()時(shí)查看實(shí)際打開(kāi)的URL地地址。

package com.gitee.funcy.jtools.btrace;

import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.Location;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.Kind;
import com.sun.btrace.annotations.ProbeClassName;
import com.sun.btrace.annotations.ProbeMethodName;
import com.sun.btrace.annotations.Self;
import static com.sun.btrace.BTraceUtils.*;

/**
 * {這里添加描述}
 *
 * @author chengyan
 * @date 2019-11-04 10:20 下午
 */
@BTrace
public class PrintField {
    @OnMethod(clazz = "/.*URL/", method = "/.*openConnection/", location = @Location(value = Kind.ENTRY))
    public static void visitWebEntry(@Self Object self, @ProbeClassName String pcn, @ProbeMethodName String pmn) {
        println(pcn + "." + pmn);
        println(self);
        // 只能取值static變量
        println(get(field(classOf(self), "protocolPathProp")));
        // 獲得實(shí)例變量
        println(get(field(classOf(self), "host"), self));
        println("===============");
    }
}

運行結果:

$ btrace 46969 PrintField.java
java.net.URL.openConnection
http://www.sina.com.cn
java.protocol.handler.pkgs
www.sina.com.cn
===============

這里監控URL對象,在調用openConnection()方法時(shí),獲得當前對象實(shí)例self,然后獲取對應實(shí)例的host等屬性。

6. 注意事項

  1. 腳本中方法參數需要跟原方法參數類(lèi)型保持一致

  2. 腳本中不允許使用除btrace之外的類(lèi),拼接字符串使用BTraceUtils.strcat(),打印使用BTraceUtils.println(),獲取線(xiàn)程使用BTraceUtils.Threads

  3. BTrace植入過(guò)的代碼,會(huì )一直在,直到應用重啟為止。所以即使Btrace退出了,業(yè)務(wù)函數每次執行時(shí)都會(huì )執行Btrace植入的代碼

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。

少妇BBB好爽| 大又大粗又爽又黄少妇毛片免费| 人人鲁免费播放视频| 欧洲人妻丰满AV无码久久不卡| 无码专区—VA亚洲V天堂| 国产在线国偷精品免费看|