<p> Java生态中有一些非正常的技術,它們能達到一些特别的效果。這些技術的實作原理不去深究的話一般并不是廣為人知。這種技術通常被稱為黑科技。而這些黑科技中的絕大部分底層都是通過JVMTI實作的。<br></p><p> 形象地說,JVMTI是Java虛拟機提供的一整套後門。通過這套後門可以對虛拟機方方面面進行監控,分析。甚至幹預虛拟機的運作。</p><p> 下面先介紹下哪些黑科技是通過JVMTI實作的,再詳細的介紹JVMTI。</p><p><span style="text-align:justify;"> </span></p><hr style="border-style:solid;border-width:1px 0 0;border-color:rgba(0,0,0,.1);"><p>JVMTI可以用來實作哪些黑科技<br></p><ol class="list-paddingleft-2" style="list-style-type:decimal;"><li><p>使用JVMTI對class檔案加密</p><p>有時一些涉及到關鍵技術的class檔案或者jar包我們不希望對外暴露,因而需要進行加密。使用一些正常的手段(例如使用混淆器或者自定義類加載器)來對class檔案進行加密很容易被反編譯。反編譯後的代碼雖然增加了閱讀的難度,但花費一些功夫也是可以讀懂的。使用JVMTI我們可以将解密的代碼封裝成.dll,或.so 檔案。這些檔案想要反編譯就很麻煩了,另外還能加殼。解密代碼不能被破解,進而也就保護了我們想要加密的class檔案。</p><p><br></p></li><li><p>使用JVMTI實作應用性能監控(APM)</p><p>在微服務大行其道的環境下,分布式系統的邏輯結構變得越來越複雜。這給系統性能分析和問題定位帶來了非常大的挑戰。基于JVMTI的APM能夠解決分布式架構和微服務帶來的監控和運維上的挑戰。APM通過彙聚業務系統各處理環節的實時資料,分析業務系統各事務處理的交易路徑和處理時間,實作對應用的全鍊路性能監測。開源的Pinpoint, ZipKin, Hawkular,商業的AppDynamics,OneAPM,Google Dapper等都是個中好手。</p><p><br></p></li><li><p>産品運作時錯誤監測及調試</p><p>想要看生産環境的異常,最原始的方式是登入到生産環境的機器檢視日志。稍微進階一點的方式是通過日志監控或者APM等工具将異常采集上來。但是這些手段都有許多明顯的缺點。首先,不是所有的異常都會被列印到日志中,有些異常可能被代碼吃掉了;其次,列印異常的時候通常隻有異常堆棧資訊,異常發生時上下文的變量值很難擷取到(除非有經驗的程式員将其列印出來了),而這些資訊對定位異常的原因至關重要。基于JVMTI可以開發出一款工具來時事監控生産環境的異常。這方面有一款成熟的商業軟體OverOps,其有三個主要的功能:1. 采集到所有的異常,包括try catch之後沒有列印出來的異常;2. 可以采集到異常發生時上下文所有變量的值;3. 可以将異常發生的堆棧對應的源代碼采集展示出來,進而在一個系統上就可以看代碼定位問題,不需要打開ide調試源代碼。</p><p><br></p></li><li><p>JAVA程式的調試(debug)。</p><p>一般JAVA的IDE都自帶了調試工具。例如Eclipse的調試器相信大部分人都使用過。它的調試器org.eclipse.jdt.debug插件底層就是調用的JVMTI來實作的。不僅如此,随着服務雲化的發展,google甚至推出了雲端調試工具cloud debugger。它時一個web應用,可以直接對生産環境進行遠端調試,不需要重新開機或者中斷服務。阿裡也有類似的工具Zdebugger。</p><p><br></p></li><li><p>JAVA程式的診斷(profile)。</p><p>當出現cpu使用率過高、線程死鎖等問題時,需要使用一些JAVA性能剖析或者診斷工具來分析具體的原因。例如Alibaba開源的Java診斷工具Arthas,深受開發者喜愛。Arthas的功能十分強大,它可以檢視或者動态修改某個變量的值、統計某個方法調用鍊上的耗時、攔截方法前後,列印參數值和傳回值,以及異常資訊等。</p><p><br></p></li><li><p>熱加載</p><p>熱加載指的是在不重新開機虛拟機的情況下重新加載一些class。熱加載可以使本地調試代碼非常節省時間,不用每次更新代碼都重新開機一邊程式。同時,在一線不友善重新開機的線上環境也能派上用場。這方面的代表産品有商業産品JRebel等。JRebel能夠對應用中的任何class起作用。</p></li></ol><p style="text-indent:0;"> </p><hr style="border-style:solid;border-width:1px 0 0;border-color:rgba(0,0,0,.1);"><p style="text-indent:0;">JVMTI是什麼<br></p><p style="text-indent:0;"> </p><ol class="list-paddingleft-2" style="list-style-type:decimal;"><li><p>JVMTI的定義及原理</p><p>在介紹JVMTI之前,需要先了解下Java平台調試體系JPDA(Java PlatformDebugger Architecture)。它是Java虛拟機為調試和監控虛拟機專門提供的一套接口。如下圖所示,JPDA被抽象為三層實作。其中JVMTI就是JVM對外暴露的接口。JDI是實作了JDWP通信協定的用戶端,調試器通過它和JVM中被調試程式通信。</p><p> JVMTI 本質上是在JVM内部的許多事件進行了埋點。通過這些埋點可以給外部提供目前上下文的一些資訊。甚至可以接受外部的指令來改變下一步的動作。外部程式一般利用C/C++實作一個JVMTIAgent,在Agent裡面注冊一些JVM事件的回調。當事件發生時JVMTI調用這些回調方法。Agent可以在回調方法裡面實作自己的邏輯。JVMTIAgent是以動态連結庫的形式被虛拟機加載的。</p><p><br></p><p><br></p><p><img class="rich_pages" src="https://img2018.cnblogs.com/blog/1112483/201912/1112483-20191228165246537-950003623.png" alt="640?wx_fmt=png"></p><p><br></p><p><br></p></li><li><p>JVMTI的曆史</p><p>JVMTI 的前身是JVMDI(Java Virtual Machine Profiler Interface) 和 JVMPI(Java Virtual Machine Debug Interface),它們原來分别被用于提供調試 Java 程式以及 Java 程式調節性能的功能。在 J2SE 5.0 之後 JDK 取代了JVMDI 和 JVMPI 這兩套接口,JVMDI 在最新的 Java SE 6 中已經不提供支援,而 JVMPI 也計劃在 Java SE 7 後被徹底取代。</p><p><br></p></li><li><p>JVMTI的功能</p><p>JVMTI處于整個JPDA 體系的最底層,所有調試功能本質上都需要通過 JVMTI 來提供。從大的方面來說,JVMTI 提供了可用于 debug 和profiler 的接口;同時,在 Java 5/6 中,虛拟機接口也增加了監聽(Monitoring),線程分析(Thread analysis)以及覆寫率分析(Coverage Analysis)等功能。從小的方面來說包含了虛拟機中線程、記憶體、堆、棧、類、方法、變量,事件、定時器處理等等諸多功能。具體可以參考oracle 的文檔:https://docs.oracle.com/javase/1.5.0/docs/guide/jvmti/jvmti.html。通過這些接口,開發人員不僅可以調試在該虛拟機上運作的 Java 程式,還能檢視它們運作的狀态,設定回調函數,控制某些環境變量,進而優化程式性能。</p><p><br></p></li><li><p>JVMTI的實作</p><p>JVMTI 并不一定在所有的 Java 虛拟機上都有實作,不同的虛拟機的實作也不盡相同。不過在一些主流的虛拟機中,比如 Sun 和 IBM,以及一些開源的如Apache Harmony DRLVM 中,都提供了标準 JVMTI 實作。</p></li></ol><p> </p><p> </p><p>參考:</p><ol style="list-style-type:decimal;" class="list-paddingleft-2"><li><p>https://docs.oracle.com/javase/1.5.0/docs/guide/jvmti/jvmti.html</p></li><li><p>https://www.ibm.com/developerworks/cn/java/j-lo-jpda2/</p></li><li><p>http://blog.caoxudong.info/blog/2017/12/07/jvmti_reference</p></li><li><p>http://lovestblog.cn/blog/2015/09/14/javaagent/</p></li><li><p>https://www.jianshu.com/p/e59c4eed44a2</p></li></ol><p> </p><p> </p><p> </p><p><br></p>
原文位址:https://blog.csdn.net/duqi_2009/article/details/94518203 </div>