Java Attach機制

一、什么是Attach機制庸追?

簡單點說就是jdk的一些工具類提供的一種jvm進程間通信的能力衅谷,能讓一個進程傳命令給另外一個進程,并讓它執(zhí)行內(nèi)部的一些操作窑眯,比如說我們?yōu)榱俗屃硗庖粋€jvm進程把線程dump出來,那么我們運行了一個jstack的進程医窿,然后給它傳了個pid的參數(shù)磅甩,告訴它要對哪個進程進行線程dump,既然是兩個進程姥卢,那肯定涉及到進程間通信卷要,以及傳輸協(xié)議的定義,比如要執(zhí)行什么操作独榴,傳了什么參數(shù)等等僧叉。

Attach機制可以對目標(biāo)進程收集很多信息,如內(nèi)存dump棺榔,線程dump彪标,類信息統(tǒng)計(比如加載的類及大小以及實例個數(shù)等),動態(tài)加載agent掷豺,動態(tài)設(shè)置vm flag(但是并不是所有的flag都可以設(shè)置的捞烟,因為有些flag是在jvm啟動過程中使用的薄声,是一次性的),打印vm flag题画,獲取系統(tǒng)屬性等等默辨,這些對應(yīng)的源碼(AttachListener.cpp)。


二苍息、Attach方法小結(jié)

1缩幸、繼承Tool/HotSpotAgent.attach(采用Serviceability?Agent,簡稱SA)

SA(Serviceability?Agent)是一個用于分析HotSpot運行時進程和Core文件中數(shù)據(jù)的工具竞思。它可以attach到Java進程或分析Core文件中的數(shù)據(jù)表谊,了解加載的class,是一個包含大量Java API和工具的工具集盖喷,目前實現(xiàn)只支持“snapshot”式的使用方式爆办。“snapshot”是指不支持在SA保持連接的同時讓目標(biāo)進程運行课梳,就是說無論如何在SA進行attach的時候目標(biāo)進程都要暫停的(SA在attatch到進程之后距辆,會暫停當(dāng)前進程的執(zhí)行,拿到的是進程的一個snapshot暮刃,當(dāng)前進程會在SA斷開后繼續(xù)執(zhí)行)跨算,所以在線上使用這類工具進行dump時無論耗時長短必須要摘流量,否則可能會使服務(wù)不可用而帶來一些不必要的影響椭懊。

SA 在JDK中是以Jar文件的形式提供的诸蚕,位于JAVA_HOME/lib/sa-jdi.jar?,和一般的Jar文件執(zhí)行一樣氧猬。

TBJMap使用了hotspot源碼的sa-jdi.jar的sun.jvm.hotspot.HotSpotAgent這個類(其中TBJMap繼承了sun.jvm.hotspot.tools.Tool這個類背犯,最終用到的也是HotSpotAgent作為代理agent,也就是使用的是SA)狂窑。

HotSpotAgent.attach方法過程分析(linux):

(1)首先通過/proc/[pid]/maps讀取elf文件,保存符號表(elf文件除了機器碼外桑腮,還包含其它額外的信息泉哈,如段的加載地址,運行地址破讨,重定位表丛晦,符號表等,比bin文件要大提陶,通過gcc編譯出來的可執(zhí)行文件是elf文件)烫沙;

(2)接著通過保存的符號表讀取HotSpotVM中l(wèi)ocalHotSpotVMStructs和localHotSpotVMTypes等變量的地址;

(3)然后使用ptrace根據(jù)變量的地址讀取SA需要用到的HotSpotVM中的數(shù)據(jù)的元信息(類型信息隙笆,字段offset锌蓄,地址等)升筏;

(4)最后根據(jù)這些元信息就可以讀取到目標(biāo)VM上這些數(shù)據(jù)的值。

在Linux平臺上瘸爽,attach方法最終是使用了/procptrace來讀取目標(biāo)VM中的數(shù)據(jù)您访,ptrace提供了一種使父進程可以監(jiān)視和控制其它進程的方式,它還能夠改變子進程中的寄存器和內(nèi)核映像剪决,因而可以實現(xiàn)斷點調(diào)試和系統(tǒng)調(diào)用的跟蹤(ptrace會使內(nèi)核暫停當(dāng)前進程并將控制權(quán)交給跟蹤進程灵汪,使跟蹤進程得以察看或者修改被跟蹤進程的寄存器,待收集完跟蹤信息以后會把控制權(quán)交回給當(dāng)前進程讓其繼續(xù)運行)柑潦。?

SA工具的attach和detach分別對應(yīng)的ptrace方法是:

ptrace(PT_ATTACH, pid, 0, 0);  
ptrace(PT_DETACH, pid, 0, 0);
??更具體源碼分析見:HotSpotAgent.attach源碼分析

2享言、VirtualMachine.attach(Attach到Attach Listener線程后執(zhí)行有限命令)

jstack和jhipcup的attach使用的是VirtualMachine.attach。

VirtualMachine.attach方法過程分析(linux):

(1)信號機制

JVM啟動的時候并不會馬上創(chuàng)建Attach Listener線程渗鬼,而是通過另外一個線程Signal Dispatcher在接收到信號處理請求(如jstack览露,jmap等)時創(chuàng)建臨時socket文件/tmp/.java_pid并創(chuàng)建Attach Listener線程(external process會先發(fā)送一個SIGQUIT信號給target VM process,target VM會創(chuàng)建一個Attach Listener線程)乍钻;

(2)Unix domain socket

Attach Listener線程會通過Unix domain socket與external process建立連接肛循,之后就可以基于這個socket進行通信了。

創(chuàng)建好的Attach Listener線程會負(fù)責(zé)執(zhí)行這些命令(從隊列里不斷取AttachOperation银择,然后找到請求命令對應(yīng)的方法進行執(zhí)行多糠,比如jstack命令,找到 { “threaddump”, thread_dump }的映射關(guān)系浩考,然后執(zhí)行thread_dump方法)并且把結(jié)果通過.java_pid文件返回給發(fā)送者夹孔。

????? 整個過程中,會有兩個文件被創(chuàng)建:

.attach_pid<pid>析孽,external process會創(chuàng)建這個文件搭伤,為的是觸發(fā)Attach Listener線程的創(chuàng)建,因為SIGQUIT信號不是只有external process才會發(fā)的袜瞬,通過這個文件來告訴target VM怜俐,有attach請求過來了(如果.attach_pid創(chuàng)建好了,說明Attach Listener線程已經(jīng)創(chuàng)建成功)邓尤。相關(guān)代碼在LinuxVirtualMachine.java中拍鲤;

.java_pid<pid>,target VM會創(chuàng)建這個文件汞扎,這個是因為Unix domain socket本身的實現(xiàn)機制需要去創(chuàng)建一個文件季稳,通過這個文件來進行IPC。相關(guān)代碼在attachListener_linux.cpp中澈魄。

其中的<pid>都是target VM的pid景鼠。

具體更詳細(xì)的VirtualMachine.attach的源碼分析見:VirtualMachine.attach源碼分析

???? Attach Listener線程命令對應(yīng)的源碼(AttachListener.cpp)如下:

static AttachOperationFunctionInfo funcs[] = {
  { "agentProperties",  get_agent_properties },
  { "datadump",         data_dump },
  { "dumpheap",         dump_heap },
  { "load",             JvmtiExport::load_agent_library },
  { "properties",       get_system_properties },
  { "threaddump",       thread_dump },
  { "inspectheap",      heap_inspection },
  { "setflag",          set_flag },
  { "printflag",        print_flag },
  { "jcmd",             jcmd },
  { NULL,               NULL }
};

?3、Perf.getPerf().attach(通過PerfData文件獲取信息)

用lsof -p 查看進程打開了哪些文件時痹扇,經(jīng)愁趵欤可以看到/tmp/hsperfdata_$username/$pid文件溯香,如:

[root@ospdev-qxtjx]# lsof -p 32098 | grep perf
java 32098 root  mem    REG   252,1   32768  934145 /tmp/hsperfdata_root/32098
?該文件其實是一個mmap內(nèi)存映射文件,JVM用來收集狀態(tài)數(shù)據(jù)給其它進程使用的票渠,可以使用-XX:+PerfDisableSharedMem來關(guān)閉它逐哈,當(dāng)?shù)竭_安全點時,JVM會把安全點的相關(guān)信息寫入到這個文件中去问顷,在使用jstack昂秃,jconsole等工具時會讀取該文件獲取內(nèi)容來統(tǒng)計信息。

perf attach源碼調(diào)用過程:

調(diào)用rt.jar包的sun.misc.Perf類的attach方法

--->調(diào)用對應(yīng)的perf.cppPerf_Attach方法--->方法里再調(diào)用PerfMemory::attach

--->最后通過方法mmap_attach_shared將GC或其他狀態(tài)相關(guān)的數(shù)據(jù)寫入到該mmap內(nèi)存映射文件(該mmap內(nèi)存映射文件是在JVM啟動時調(diào)用PerfMemory::create_memory_region就已經(jīng)創(chuàng)建好的)杜窄。

?jstat肠骆,sjk等工具通過訪問該mmap內(nèi)存映射文件,讀取到相關(guān)的內(nèi)容塞耕,顯示在屏幕上蚀腿。

4、幾種命令工具的attach方式的比較

(1)幾種attach方式的比較:

幾種attach方式的比較

(2)命令工具以及它的所屬系列及對應(yīng)的代碼入口:

命令工具以及它的所屬系列及對應(yīng)的代碼入口

(3)命令工具以及它所對應(yīng)的attach方式:

命令工具以及它所對應(yīng)的attach方式

jmap和jstack的“-F”參數(shù)可以把原先VirtualMachine.attach方式強制改為SA attach方式扫外,命令如下:

jmap -F -histo <pid>
jstack -F <pid>
jstack -F -l <pid>


參考文獻:

1莉钙、JVM源碼分析之Attach機制實現(xiàn)完全解讀(你假笨)

2、HotSpot Serviceability Agent 實現(xiàn)淺析

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末筛谚,一起剝皮案震驚了整個濱河市磁玉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌驾讲,老刑警劉巖蚊伞,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異吮铭,居然都是意外死亡时迫,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門谓晌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掠拳,“玉大人,你說我怎么就攤上這事纸肉∧缗罚” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵毁靶,是天一觀的道長胧奔。 經(jīng)常有香客問我逊移,道長预吆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任胳泉,我火速辦了婚禮拐叉,結(jié)果婚禮上岩遗,老公的妹妹穿的比我還像新娘。我一直安慰自己凤瘦,他們只是感情好宿礁,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蔬芥,像睡著了一般梆靖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上笔诵,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天返吻,我揣著相機與錄音,去河邊找鬼乎婿。 笑死测僵,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的谢翎。 我是一名探鬼主播捍靠,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼森逮!你這毒婦竟也來了榨婆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤吊宋,失蹤者是張志新(化名)和其女友劉穎纲辽,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體璃搜,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡拖吼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了这吻。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吊档。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖唾糯,靈堂內(nèi)的尸體忽然破棺而出怠硼,到底是詐尸還是另有隱情,我是刑警寧澤移怯,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布香璃,位于F島的核電站,受9級特大地震影響舟误,放射性物質(zhì)發(fā)生泄漏葡秒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望眯牧。 院中可真熱鬧蹋岩,春花似錦、人聲如沸学少。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽版确。三九已至扣囊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間绒疗,已是汗流浹背如暖。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留忌堂,地道東北人盒至。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像士修,于是被迫代替她去往敵國和親枷遂。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Attach是什么 在講這個之前棋嘲,我們先來點大家都知道的東西酒唉,當(dāng)我們感覺線程一直卡在某個地方,想知道卡在哪里沸移,首先...
    jerrik閱讀 1,080評論 0 1
  • 從JDK6開始引入痪伦,除了Solaris平臺的Sun JVM支持遠程的Attach,在其他平臺都只允許Attach到...
    andersonoy閱讀 3,438評論 0 3
  • Linux SignalsStandard SignalsLinux supports the standard ...
    andersonoy閱讀 673評論 0 0
  • 最近因為需求雹锣,這周學(xué)習(xí)了html的一些內(nèi)容网沾。整理了下常用的這些標(biāo)簽。
    OSong閱讀 155評論 0 0
  • 一件藍布褂 滿頭銀絲 兩只渾濁的眼睛 右手拄著一根拐棍 左手端著葫蘆瓢 從遠處蹣跚而來 我的大姥姥 爬到樹上頑皮的...
    沐葉_93f1閱讀 179評論 0 9