JAVA-JVMTI

一、JVMTI簡(jiǎn)介

JVMTI(JVM tool interface)位于jpda最底層,JVMTI是JPDA中的一環(huán)
JPDA叫做Java 平臺(tái)調(diào)試架構(gòu)(Java Platform Debugger Architecture)

Java平臺(tái)調(diào)試體系JPDA(Java PlatformDebugger Architecture)。它是Java虛擬機(jī)為調(diào)試和監(jiān)控虛擬機(jī)專門提供的一套接口。如下圖所示,JPDA被抽象為三層實(shí)現(xiàn)。其中JVMTI就是JVM對(duì)外暴露的接口。JDI是實(shí)現(xiàn)了JDWP通信協(xié)議的客戶端,調(diào)試器通過(guò)它和JVM中被調(diào)試程序通信。

  JVMTI 本質(zhì)上是在JVM內(nèi)部的許多事件進(jìn)行了埋點(diǎn)。通過(guò)這些埋點(diǎn)可以給外部提供當(dāng)前上下文的一些信息。甚至可以接受外部的命令來(lái)改變下一步的動(dòng)作。外部程序一般利用C/C++實(shí)現(xiàn)一個(gè)JVMTIAgent,在Agent里面注冊(cè)一些JVM事件的回調(diào)。當(dāng)事件發(fā)生時(shí)JVMTI調(diào)用這些回調(diào)方法。Agent可以在回調(diào)方法里面實(shí)現(xiàn)自己的邏輯。JVMTIAgent是以動(dòng)態(tài)鏈接庫(kù)的形式被虛擬機(jī)加載的。

這三個(gè)規(guī)范把調(diào)試過(guò)程分解成幾個(gè)概念:調(diào)試者(debugger)、被調(diào)試者(debuggee)、以及它們中間的通信器

JVMTI(Java Virtual Machine Tool Interface)即指 Java 虛擬機(jī)工具接口,它是一套由虛擬機(jī)直接提供的 native 接口,它處于整個(gè) JPDA 體系的最底層,所有調(diào)試功能本質(zhì)上都需要通過(guò) JVMTI 來(lái)提供。
通過(guò)這些接口,開(kāi)發(fā)人員不僅調(diào)試在該虛擬機(jī)上運(yùn)行的 Java 程序,還能查看它們運(yùn)行的狀態(tài),設(shè)置回調(diào)函數(shù),控制某些環(huán)境變量,從而優(yōu)化程序性能。
JVMTI 本質(zhì)上是在 JVM 內(nèi)部的許多事件進(jìn)行了埋點(diǎn)。通過(guò)這些埋點(diǎn)可以給外部提供當(dāng)前上下文的一些信息。甚至可以接受外部的命令來(lái)改變下一步的動(dòng)作。
外部程序一般利用C/C++實(shí)現(xiàn)一個(gè)JVMTIAgent,在Agent里面注冊(cè)一些JVM事件的回調(diào)。當(dāng)事件發(fā)生時(shí)JVMTI調(diào)用這些回調(diào)方法。Agent可以在回調(diào)方法里面實(shí)現(xiàn)自己的邏輯。JVMTIAgent是以動(dòng)態(tài)鏈接庫(kù)的形式被虛擬機(jī)加載的。

JVMTI的歷史
JVMTI 的前身是 JVMDI(Java Virtual Machine Debug Interface)和 JVMPI(Java Virtual Machine Profiler Interface),它們?cè)瓉?lái)分別被用于提供調(diào)試 Java 程序以及 Java 程序調(diào)節(jié)性能的功能。在 J2SE 5.0 之后 JDK 取代了JVMDI 和 JVMPI 這兩套接口,JVMDI 在最新的 Java SE 6 中已經(jīng)不提供支持,而 JVMPI 也計(jì)劃在 Java SE 7 后被徹底取代。

JVMTI的功能

JVMTI處于整個(gè)JPDA 體系的最底層,所有調(diào)試功能本質(zhì)上都需要通過(guò) JVMTI 來(lái)提供。從大的方面來(lái)說(shuō),JVMTI 提供了可用于 debug 和profiler 的接口;同時(shí),在 Java 5/6 中,虛擬機(jī)接口也增加了監(jiān)聽(tīng)(Monitoring),線程分析(Thread analysis)以及覆蓋率分析(Coverage Analysis)等功能。從小的方面來(lái)說(shuō)包含了虛擬機(jī)中線程、內(nèi)存、堆、棧、類、方法、變量,事件、定時(shí)器處理等等諸多功能。具體可以參考o(jì)racle 的文檔:https://docs.oracle.com/javase/1.5.0/docs/guide/jvmti/jvmti.html。通過(guò)這些接口,開(kāi)發(fā)人員不僅可以調(diào)試在該虛擬機(jī)上運(yùn)行的 Java 程序,還能查看它們運(yùn)行的狀態(tài),設(shè)置回調(diào)函數(shù),控制某些環(huán)境變量,從而優(yōu)化程序性能。

JVMTI的實(shí)現(xiàn)

JVMTI 并不一定在所有的 Java 虛擬機(jī)上都有實(shí)現(xiàn),不同的虛擬機(jī)的實(shí)現(xiàn)也不盡相同。不過(guò)在一些主流的虛擬機(jī)中,比如 Sun 和 IBM,以及一些開(kāi)源的如Apache Harmony DRLVM 中,都提供了標(biāo)準(zhǔn) JVMTI 實(shí)現(xiàn)。

JVMTI可以用來(lái)實(shí)現(xiàn)哪些黑科技

使用JVMTI對(duì)class文件加密

有時(shí)一些涉及到關(guān)鍵技術(shù)的class文件或者jar包我們不希望對(duì)外暴露,因而需要進(jìn)行加密。使用一些常規(guī)的手段(例如使用混淆器或者自定義類加載器)來(lái)對(duì)class文件進(jìn)行加密很容易被反編譯。反編譯后的代碼雖然增加了閱讀的難度,但花費(fèi)一些功夫也是可以讀懂的。使用JVMTI我們可以將解密的代碼封裝成.dll,或.so 文件。這些文件想要反編譯就很麻煩了,另外還能加殼。解密代碼不能被破解,從而也就保護(hù)了我們想要加密的class文件。

使用JVMTI實(shí)現(xiàn)應(yīng)用性能監(jiān)控(APM)

在微服務(wù)大行其道的環(huán)境下,分布式系統(tǒng)的邏輯結(jié)構(gòu)變得越來(lái)越復(fù)雜。這給系統(tǒng)性能分析和問(wèn)題定位帶來(lái)了非常大的挑戰(zhàn)。基于JVMTI的APM能夠解決分布式架構(gòu)和微服務(wù)帶來(lái)的監(jiān)控和運(yùn)維上的挑戰(zhàn)。APM通過(guò)匯聚業(yè)務(wù)系統(tǒng)各處理環(huán)節(jié)的實(shí)時(shí)數(shù)據(jù),分析業(yè)務(wù)系統(tǒng)各事務(wù)處理的交易路徑和處理時(shí)間,實(shí)現(xiàn)對(duì)應(yīng)用的全鏈路性能監(jiān)測(cè)。開(kāi)源的Pinpoint, ZipKin, Hawkular,商業(yè)的AppDynamics,OneAPM,Google Dapper等都是個(gè)中好手。

產(chǎn)品運(yùn)行時(shí)錯(cuò)誤監(jiān)測(cè)及調(diào)試

想要看生產(chǎn)環(huán)境的異常,最原始的方式是登錄到生產(chǎn)環(huán)境的機(jī)器查看日志。稍微高級(jí)一點(diǎn)的方式是通過(guò)日志監(jiān)控或者APM等工具將異常采集上來(lái)。但是這些手段都有許多明顯的缺點(diǎn)。首先,不是所有的異常都會(huì)被打印到日志中,有些異常可能被代碼吃掉了;其次,打印異常的時(shí)候通常只有異常堆棧信息,異常發(fā)生時(shí)上下文的變量值很難獲取到(除非有經(jīng)驗(yàn)的程序員將其打印出來(lái)了),而這些信息對(duì)定位異常的原因至關(guān)重要。基于JVMTI可以開(kāi)發(fā)出一款工具來(lái)時(shí)事監(jiān)控生產(chǎn)環(huán)境的異常。這方面有一款成熟的商業(yè)軟件OverOps,其有三個(gè)主要的功能:1. 采集到所有的異常,包括try catch之后沒(méi)有打印出來(lái)的異常;2. 可以采集到異常發(fā)生時(shí)上下文所有變量的值;3. 可以將異常發(fā)生的堆棧對(duì)應(yīng)的源代碼采集展示出來(lái),從而在一個(gè)系統(tǒng)上就可以看代碼定位問(wèn)題,不需要打開(kāi)ide調(diào)試源代碼。

JAVA程序的調(diào)試(debug)。

一般JAVA的IDE都自帶了調(diào)試工具。例如Eclipse的調(diào)試器相信大部分人都使用過(guò)。它的調(diào)試器org.eclipse.jdt.debug插件底層就是調(diào)用的JVMTI來(lái)實(shí)現(xiàn)的。不僅如此,隨著服務(wù)云化的發(fā)展,google甚至推出了云端調(diào)試工具cloud debugger。它時(shí)一個(gè)web應(yīng)用,可以直接對(duì)生產(chǎn)環(huán)境進(jìn)行遠(yuǎn)程調(diào)試,不需要重啟或者中斷服務(wù)。阿里也有類似的工具Zdebugger。

JAVA程序的診斷(profile)。

當(dāng)出現(xiàn)cpu使用率過(guò)高、線程死鎖等問(wèn)題時(shí),需要使用一些JAVA性能剖析或者診斷工具來(lái)分析具體的原因。例如Alibaba開(kāi)源的Java診斷工具Arthas,深受開(kāi)發(fā)者喜愛(ài)。Arthas的功能十分強(qiáng)大,它可以查看或者動(dòng)態(tài)修改某個(gè)變量的值、統(tǒng)計(jì)某個(gè)方法調(diào)用鏈上的耗時(shí)、攔截方法前后,打印參數(shù)值和返回值,以及異常信息等。

熱加載

熱加載指的是在不重啟虛擬機(jī)的情況下重新加載一些class。熱加載可以使本地調(diào)試代碼非常節(jié)省時(shí)間,不用每次更新代碼都重啟一邊程序。同時(shí),在一線不方便重啟的線上環(huán)境也能派上用場(chǎng)。這方面的代表產(chǎn)品有商業(yè)產(chǎn)品JRebel等。JRebel能夠?qū)?yīng)用中的任何class起作用。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,179評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 175,628評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,642評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,444評(píng)論 6 405
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 54,948評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,185評(píng)論 0 287
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,717評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,602評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,794評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,045評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,418評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,671評(píng)論 1 281
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,414評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,750評(píng)論 2 370

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