HotSpot SA(Serviceability Agent)實(shí)現(xiàn)原理

占小狼,轉(zhuǎn)載請(qǐng)注明原創(chuàng)出處,謝謝!

jmap、jstack等工具可以訪問虛擬機(jī)中的堆對(duì)象、線程信息等,可以通過兩種方式實(shí)現(xiàn)
1、attach方式
2、SA方式

attach方式

這種方式,在之前的文章已經(jīng)分析過,底層通過socket進(jìn)行通信,jmap進(jìn)程好比一個(gè)客戶端,運(yùn)行的虛擬機(jī)看成服務(wù)端,有一個(gè)叫"Attach Listener"的線程,專門負(fù)責(zé)監(jiān)聽attach的請(qǐng)求,并在虛擬機(jī)中執(zhí)行對(duì)應(yīng)的代碼。

更多詳情點(diǎn)擊 jmap命令的實(shí)現(xiàn)原理解析

SA方式

首先,我們先看看SA可以做什么?
1、從運(yùn)行的Java進(jìn)程中讀取數(shù)據(jù)
2、從數(shù)據(jù)中,解析出所有Hotspot數(shù)據(jù)結(jié)構(gòu)
3、從Hotspot數(shù)據(jù)結(jié)構(gòu)中國(guó),解析出所有的Java對(duì)象

這里需要清楚的是:
SA是運(yùn)行在單獨(dú)的進(jìn)程中,和目標(biāo)Java進(jìn)程是隔離的,而且在使用SA工具時(shí),不會(huì)在目標(biāo)Java進(jìn)程中執(zhí)行任何代碼,而是讀取目標(biāo)Java進(jìn)程中的數(shù)據(jù),然后在自身進(jìn)程中處理,在SA讀取數(shù)據(jù)時(shí),目標(biāo)Java進(jìn)程會(huì)被掛起。

那么,SA是如何讀取到目標(biāo)Java進(jìn)程的呢?不同的系統(tǒng),有不同的方式:
1、Solaris系統(tǒng)中,通過 libproc 實(shí)現(xiàn)
2、Linux系統(tǒng)中,通過 /proc和ptrace 實(shí)現(xiàn)
3、Windows系統(tǒng)中,通過 dbgeng.dll library 實(shí)現(xiàn)

下面以Linux為例,看看是如何一步一步實(shí)現(xiàn)的。

假設(shè)執(zhí)行"jmap -heap <pid>",該命令對(duì)應(yīng)的實(shí)現(xiàn)類
"sun.jvm.hotspot.tools.HeapSummary.java"

SA的工具類都繼承了Tool類,通過start方法啟動(dòng),start方法中會(huì)初始化一個(gè)BugSpotAgent,并通過BugSpotAgent的attach方法與目標(biāo)Java進(jìn)程建立聯(lián)系,attach方法實(shí)現(xiàn)如下:

在setupDebugger方法中,根據(jù)不同平臺(tái)初始化debugger,attach動(dòng)作最終由具體的平臺(tái)相關(guān)的JVMDebugger對(duì)象完成,在Linux平臺(tái),使用LinuxDebuggerLocal對(duì)象,LinuxDebuggerLocal類中具體的attach實(shí)現(xiàn)如下:

最終調(diào)用了一個(gè)本地方法

private native void attach0(int pid) throws DebuggerException;

本地方法attach0的實(shí)現(xiàn)位于LinuxDebuggerLocal.c

在本地方法attach0中,看到有一個(gè)Pgrab方法,跟進(jìn)去...

Pgrab方法的注釋也說明該方法可以attach到目標(biāo)進(jìn)程上,從ptrace_attach方法再跟進(jìn)去...

這里,我們看到了ptrace命令

ptrace(PTRACE_ATTACH, pid, NULL, NULL)

其中PTRACE_ATTACH,可以實(shí)現(xiàn)attach到一個(gè)指定pid的進(jìn)程。

SA成功attach到目標(biāo)Java進(jìn)程之后,執(zhí)行setupVM,初始化Hotspot數(shù)據(jù)結(jié)構(gòu),之后的數(shù)據(jù)獲取通過/proc實(shí)現(xiàn),這里不再深入分析了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、什么是Attach機(jī)制? 簡(jiǎn)單點(diǎn)說就是jdk的一些工具類提供的一種jvm進(jìn)程間通信的能力,能讓一個(gè)進(jìn)程傳命令給...
    俠客楊歌閱讀 10,568評(píng)論 0 6
  • Linux SignalsStandard SignalsLinux supports the standard ...
    andersonoy閱讀 841評(píng)論 0 0
  • 簡(jiǎn)書 占小狼,轉(zhuǎn)載請(qǐng)注明原創(chuàng)出處,謝謝! 當(dāng)服務(wù)發(fā)生GC問題時(shí),一般會(huì)使用jmap工具進(jìn)行分析,jmap工具很強(qiáng)大...
    美團(tuán)Java閱讀 11,816評(píng)論 2 40
  • 序 本文主要研究一下openjdk的jhsdb工具 sa-jdi.jar 在java9之前,JAVA_HOME/l...
    go4it閱讀 9,246評(píng)論 0 4
  • JVM常用的命令 jps :基礎(chǔ)工具 查看JAVA進(jìn)程PID。 jps 命令用來查看所有 Java 進(jìn)程,每一行就...
    最怕的其實(shí)是孤單閱讀 470評(píng)論 0 0

友情鏈接更多精彩內(nèi)容