在Windows上运行-XX:CompileCommand
HotSpot JVM提供了幾個與即時 ( JIT )編譯有關的命令行參數。 在本文中,我介紹了開始應用命令行標志-XX:CompileCommand所需的步驟,以查看對單個方法執行的即時編譯。
JIT概述
Nikita Salnikov-Tarnovski的博客文章您是否能及時編譯? 很好地概述了JIT編譯器以及為什么需要它。 以下是該描述的摘錄:
歡迎–熱點。 該名稱源自JVM識別應用程序中“熱點”(經常執行的字節代碼塊)的功能。 然后將它們作為目標,以進行廣泛的優化并將其編譯為處理器專用指令。 …JVM中負責這些優化的組件稱為即時編譯器(JIT)。 …Java HotSpot VM不會及時編譯所有代碼,而是立即使用解釋器運行程序,并在運行時分析代碼以檢測程序中的關鍵熱點。 然后,它將全球本地代碼優化器的注意力集中在熱點上。
IBM文檔JIT編譯器概述還提供了JIT的簡要概述,并指出以下內容:
實際上,方法不是在第一次調用時編譯的。 對于每種方法,JVM維護一個調用計數,每次調用該方法時,該計數都會增加。 JVM解釋一個方法,直到其調用計數超過JIT編譯閾值為止。 因此,經常使用的方法在JVM啟動后立即進行編譯,而較少使用的方法則在以后編譯,或者根本不編譯。 JIT編譯閾值可幫助JVM快速啟動,并仍具有改進的性能。 精心選擇了閾值,以在啟動時間和長期性能之間獲得最佳平衡。
識別JIT編譯方法
因為JIT編譯僅在調用和解釋了-XX:CompileThreshold指定的次數( 針對服務器JVM 10,000以及針對客戶端JVM 5,000 )指定的次數之后才針對特定方法“啟動”,所以并非所有方法都將被編譯JIT編譯器。 HotSpot命令行選項-XX:+ PrintCompilation對于確定哪些方法已達到此閾值并已進行編譯非常有用。 使用此選項顯示的任何輸出方法都是已編譯方法,可以使用-XX:CompileCommand收集其編譯詳細信息。
以下屏幕快照演示了如何使用-XX:+PrintCompilation標識JIT編譯的方法。 所顯示的方法都不是簡單應用程序本身的方法。 所有方法運行的時間足以滿足從解釋到實時編譯的閾值,是“系統”方法。
使用-XX:CompileCommand “ 在指定方法的編譯后打印生成的匯編代碼 ”的前提條件之一是使用-XX:+ UnlockDiagnosticVMOptions “ 解鎖用于診斷JVM的選項 ”。
針對查看JIT編譯創建的“生成的匯編程序代碼”的方法運行-XX:CompileCommand所需的另一個依賴項是包含反匯編程序插件 。 Project Kenai包含用于熱點下載的Basic Disassembler插件頁面 ,可用于訪問這些插件 ,但是Kenai Project正在關閉 。 在線資源“ 如何在Windows上構建hsdis-amd64.dll和hsdis-i386.dll”詳細介紹了如何為Windows構建反匯編程序插件。 Lukas Stadler記錄了對反匯編程序插件的需求,并提供了指向“ Windows x86預編譯二進制文件” hsdis-i386.zip 。
我發現訪問Windows兼容反匯編程序插件的最簡單方法是從http://fcml-lib.com/download.html的免費代碼操縱庫 (FCML)下載頁面下載該插件。 撰寫本文時,最新下載版本為fcml-1.1.1(04.08.2015) 。 可以為“用于64位Java VM的可從外部加載的反匯編程序插件”下載hsdis-1.1.1-win32-amd64.zip并提供其他下載選項,如下一個屏幕快照所示。
下一個屏幕快照演示了一個錯誤,如果未下載此反匯編程序插件并將其放置在正確的目錄中,將會發生此錯誤。
錯誤消息指出:“ 無法加載hsdis-amd64.dll; 庫不可加載; PrintAssembly已禁用 ”。 ZIP文件hsdis-1.1.1-win32-amd64.zip有一個hsdis-amd64.dll ,可以從FMCL下載 。 現在,我們只需要從ZIP文件中提取hsdis-amd64.dll文件,然后將其復制到相應的JRE目錄中即可。
需要將反匯編程序插件JAR放置在與運行Java啟動器( java )時應用的JRE相關的jre/bin/server或jre/bin/client目錄中。 就我而言,我知道我的路徑已定義為可以根據我的JAVA_HOME環境變量設置從JRE獲取Java可執行文件(包括Java啟動器)。 下一個屏幕快照顯示了哪個目錄,我將需要將反匯編程序插件JAR復制到JDK的“ jre”目錄中,而不是復制到非JDK的“ jre”目錄中。
知道我的Java啟動器( java )已用完JDK的“ jre”安裝后,我知道需要將反匯編程序插件JAR復制到該目錄下的相應子目錄中。 在我的情況下,有一個“服務器”子目錄,沒有“客戶機”子目錄,因此我想將反匯編程序插件JAR復制到%JAVA_HOME%\jre\bin\server 。
看到JIT編譯方法生成的匯編代碼
通過將反匯編程序插件JAR復制到我的JRE的bin/server子目錄中,我現在可以包括命令行選項-XX:CompileCommand =print并帶有特定的方法名稱,以查看JIT編譯時該方法生成的匯編代碼。 就我而言,由于我自己的簡單應用程序沒有任何方法可以解釋足夠的時間來觸發JIT,因此我將監視“系統”方法。 在這種情況下,我指定選項“ -XX:CompileCommand=print,java/lang/String.hashCode ”打印出String.hashCode()方法生成的匯編代碼。 下一個屏幕快照對此進行了演示。
此屏幕快照包括幾個確認,我們已經使用-XX:CompileCommand正確設置了必要的依賴-XX:CompileCommand 。 這些確認包括消息的存在,“從...加載反匯編程序”和“解碼編譯方法...”。 僅僅存在比以前更多的輸出以及存在匯編程序代碼,這些都是對成功使用-XX:CompilerCommand來打印方法生成的匯編程序代碼的明顯驗證。
解密匯編代碼
至此,真正的工作開始了。 現在可以分析已打印的生成的匯編代碼,并且可以基于此分析來更改方法。 當然,這類工作需要匯編語法的知識。
我沒有在本文中介紹選項-XX:+ PrintAssembly ,因為一次查看所有生成的匯編代碼與查看特定選擇的方法的匯編代碼很少有用。 我喜歡馬丁·湯普森(Martin Thompson) 闡明的問題,“ [使用-XX:+PrintAssembly ]會使您處于無法看到森林的狀況?!?
結論
HotSpot JVM選項-XX:CompileCommand對于影響和監視即時編譯器的行為很有用。 這篇文章展示了如何使用“ print ”命令在Windows環境中應用該選項,以查看為該方法生成的匯編代碼,該方法已經被解釋了足夠多次,可以被編譯為匯編代碼,以便日后訪問。
翻譯自: https://www.javacodegeeks.com/2016/09/running-xxcompilecommand-windows.html
總結
以上是生活随笔為你收集整理的在Windows上运行-XX:CompileCommand的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js 随机1-10随机数_寻找随机的错误
- 下一篇: idea如何把包变为模块_让我们将包变成