日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

在运行期通过反射了解JVM内部机制

發(fā)布時間:2025/3/21 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在运行期通过反射了解JVM内部机制 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在日常工作中,我們都習(xí)慣直接使用或者通過框架使用反射。在沒有反射相關(guān)硬編碼知識的情況下,這是Java和Scala編程中使用的類庫與我們的代碼之間進(jìn)行交互的一種主要手段。但是,使用反射僅限于JVM內(nèi)部運行的Java和Scala代碼。假使在運行期通過反射既能查看自己的代碼又能看到JVM的代碼,會有怎樣的效果呢 ?

當(dāng)我們開始創(chuàng)建?Takipi?的時候,試圖尋找一種通過分析JVM堆內(nèi)存來進(jìn)行一些底層優(yōu)化的有效方法,比如掃描一個托管堆塊(managed heap block)的地址空間。我們找到了許多有趣的工具和組件用來檢測JVM狀態(tài)的各個方面,其中一個就是在運行期通過反射了解JVM內(nèi)部機(jī)制。

譯注:?Takipi是一家以色列創(chuàng)業(yè)公司,發(fā)現(xiàn)了一種構(gòu)建后端服務(wù)器網(wǎng)絡(luò)的新方式,可以使用非常簡化的除錯流程幫助企業(yè)定位錯誤。

Java可服務(wù)性代理(Serviceablity?Agent,簡寫SA)是最強大和最底層的Java調(diào)試工具之一。這個強大的工具是HotSpot?JDK自帶的。使用它不僅可以看到堆中的Java對象,還可以看到內(nèi)部 C++?對象,包括JVM本身。那才是真正魔法開始的地方。

反射的構(gòu)成:在運行時動態(tài)檢測和修改對象時,無論使用何種形式的反射都不能缺少兩個必要信息。第一個是想要檢測的對象引用(或者地址);第二個是對象結(jié)構(gòu)描述,包括所有字段的偏移量以及它們的類型信息。如果支持動態(tài)方法調(diào)用,這個結(jié)構(gòu)還需要包括類方法表 (比如?vtable)的引用,以及每個方法需要的參數(shù)。

Java反射本身是非常簡單的,通過反射獲取目標(biāo)對象的引用與獲取其它方式一樣。使用 Object.getClass?通用方法(最開始從類的字節(jié)碼中加載)獲取字段和方法結(jié)構(gòu)。真正的問題是:如何反射JVM本身?

反射的關(guān)鍵:令人驚奇的是, JVM通過一套公開的輸出符號暴露了其內(nèi)部的類型系統(tǒng)。?這些符號給可服務(wù)性代理(或其他工具)提供了訪問JVM內(nèi)部類系統(tǒng)結(jié)構(gòu)和地址的方法。通過這些符號,幾乎可以檢測到JVM內(nèi)部在最底層運行機(jī)制的所有方面,包括諸如原始堆地址、線程/棧地址以及編譯器內(nèi)部狀態(tài)等。

反射實戰(zhàn):為了增加對這種方式的了解,啟動可服務(wù)性代理的HotSpot調(diào)試程序界面,可以看到正在運行的一些功能。將 sun.jvm.hotspot.HSDB 作為主類參數(shù)啟動 sa-jdi.jar,可以看到與其它JVM功能強大調(diào)試工具,例如?jmap、jinfo?和?jstack等,一樣的底層信息。

HSDB及其為目標(biāo)JVM提供的一些非常底層的檢測功能

具體實現(xiàn):讓我們仔細(xì)了解這些由JVM提供的功能。這種方法的基礎(chǔ)是由?jvm 函數(shù)庫公開導(dǎo)出的 gHotSpotVMStructs?結(jié)構(gòu)。這個結(jié)構(gòu)暴露了JVM內(nèi)部的類型系統(tǒng),也為我們提供了可以開始反射的根對象地址??梢酝ㄟ^?JNI?或者?JNA訪問這個符號,調(diào)用方式與訪問動態(tài)鏈接的操作系統(tǒng)公開系統(tǒng)庫符號一樣。

接下來問題就變成:怎樣解析由?gHotSpotVMStructs 符號中地址的數(shù)據(jù)?從下表中可以看到,JVM不僅暴露了類型系統(tǒng)的地址以及根對象地址,還提供一些額外的符號用來解析需要的數(shù)據(jù)值。這些數(shù)據(jù)包括已定位的類描述符及其二進(jìn)制偏移量。

jvm.dll暴露符號的一個dependency walker截圖

清單(manifest): gHotSpotVMStructs 結(jié)構(gòu)指向了類及其字段的一個列表,每個類提供了一個字段列表。對于每個字段,該結(jié)構(gòu)提供了它的名稱、類型以及是否靜態(tài)字段。如果是一個靜態(tài)字段,這個結(jié)構(gòu)還會提供目標(biāo)對象的訪問地址。該地址可用作反射JVM內(nèi)部特定組件的根,包括諸如編譯器、線程處理或者收集堆系統(tǒng)等。

可以從這里檢出 Hotspot?JDK 中可服務(wù)性代理用來解析?gHotSpotVMStructs 的實際算法。

實例:既然已經(jīng)大概了解了這些功能,現(xiàn)在看一些由該接口訪問數(shù)據(jù)類型的示例。那些編寫SA代理的人,在為gHotSpotVMStructs表中的類創(chuàng)建Java封裝時克服了很多麻煩。在訪問大多數(shù)內(nèi)部系統(tǒng)時,這些封裝提供一套簡潔的API,不僅類型安全而且還隱藏了一些解析數(shù)據(jù)所必須的二進(jìn)制工作。

為了更好地了解這些API提供的強大功能,下面是其中的一些底層類介紹:

  • VM?是一個單例類,它暴露了JVM的許多內(nèi)部系統(tǒng),比如線程系統(tǒng)、內(nèi)存管理以及集合功能。可以把它當(dāng)作JVM許多子系統(tǒng)的一個入口。當(dāng)你研究API時,可以從這里入手。
  • JavaThread?可以讓你從JVM角度理解一個Java線程,?同時還有(編譯后的、經(jīng)過解釋的和本地)幀位置和類型的深入信息以及實際的本地堆棧和CPU寄存器信息。
  • CollectedHeap?可以讓你研究收集堆(collected heap)的原始內(nèi)容。由于HotSpot包含多種GC的實現(xiàn),CollectedHeap 就是供具體實現(xiàn)比如?ParallelScavengeHeap?必須繼承的抽象類。每一個都提供包含Java對象實際地址的一組內(nèi)存區(qū)域。

當(dāng)你在看每個類的實現(xiàn)時,你會發(fā)現(xiàn)本質(zhì)上它們就是使用類似反射API來查看JVM內(nèi)存硬編碼的包裝器。

C++中的反射:這些Java包裝器中的每一個都被設(shè)計為JVM內(nèi)部一個近乎完整的C++類鏡像。我們知道,C++?沒有原生的反射能力,這就讓我們產(chǎn)生了一個疑問:如何在這之間建立的紐帶?

答案就是JVM開發(fā)者所了一些非常特別的事情。經(jīng)過一系列C++宏指令以及大量的艱苦工作,HotSpot?開發(fā)小組手動將許多內(nèi)部C++類的字段結(jié)構(gòu)映射并加載到全局的 gHotSpotVMStructs 中。這個過程就是可以從外部進(jìn)行反射的原因。在JVM編譯期間確定了實際字段偏移量的值和布局,幫助并確保了輸出結(jié)構(gòu)兼容JVM目標(biāo)操作系統(tǒng)。

跨進(jìn)程連接:可服務(wù)性代理有另外一個強大的功能值得我們關(guān)注。從進(jìn)程外反射一個內(nèi)部運行的JVM是SA框架提供的超酷功能之一,通過把可服務(wù)性代理附加到目標(biāo)JVM作為一個操作系統(tǒng)級別的調(diào)試器可以實現(xiàn)這一功能。由于 SA?代理框架是依賴于操作系統(tǒng)的,對于?Linux 會利用 gdb?調(diào)試器進(jìn)行連接,對于Windows 則會使用winDbg (這意味著需要Windows?調(diào)試工具)。調(diào)試器框架是可擴(kuò)展的,這意味著可以通過繼承?DebuggerBase?這個抽象類來使用另一個調(diào)試器。

一旦建立了調(diào)試器的連接,gHotSpotVMStruct的返回地址值會傳回到調(diào)試器進(jìn)程,這樣可以(借助操作系統(tǒng))開始檢測甚至是修改目標(biāo)JVM的內(nèi)部對象系統(tǒng)。這就是HSDB如何實現(xiàn)連接并調(diào)試一個目標(biāo)JVM,包括Java代碼和JVM代碼。

HSDB接口為SA代理提供了反射目標(biāo)JVM進(jìn)程功能

希望本文能夠勾起你的興趣。 以我個人觀點來看,這個架構(gòu)是我最喜歡的JVM設(shè)計之一?。它的優(yōu)雅和開放絕對令人驚嘆。在我們構(gòu)建?Takipi?實時編碼模塊時超級有用,?所以要感謝它的設(shè)計者。

你是否已經(jīng)在代碼中使用了這些API?非常樂意在下面的評論中聽到它,或者回答你們的任何問題。

原文鏈接:? takipioncode ?翻譯:? ImportNew.com? -? 黃飛飛
譯文鏈接:? http://www.importnew.com/8631.html

總結(jié)

以上是生活随笔為你收集整理的在运行期通过反射了解JVM内部机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。