在任何給定的時刻
JVM進程包含一些可執行文件和一些使用JIT編譯的代碼
它們被動態鏈接到JVM中的MMI方法的封裝程序上
JIT編譯的本地機器代碼被放置到JVM本地數據內存段中
這樣就可以增加JVM進程的本地內存占用
並且MMI封裝程序被修改為指向編譯後的代碼
JIT診斷
本節將介紹在問題發生時用來調試和診斷IBM JVM的JIT和MMI的技術
上一節簡要介紹了JIT
它是IBM JVM的一個基本部分
在任何給定的時刻
JVM進程包含一些可執行文件和一些使用JIT編譯的代碼
它們被動態鏈接到JVM中的MMI方法的封裝程序上
JIT編譯的本地機器代碼被放置到JVM本地數據內存段中
這樣就可以增加JVM進程的本地內存占用
並且MMI封裝程序被修改為指向編譯後的代碼
因此
JIT對於Java程序的執行流程會產生很大的影響
◆在將程序從一個平台上遷移到另外一個平台上碰到的問題如下
死鎖掛起
一直產生不正確的結果
結果不一致
不正常結束
無限循環
內存洩漏
對問題原因要考慮的第一件事情是JIT
盡快在判斷問題原因時
確定JIT是否是問題的根源非常重要
這是由於
個原因
◆問題可能是由於JIT在JVM中給定的活動角色而引起的
◆JIT調試與其他類型的問題判斷技術有很大的不同
◆JIT調試過程可能會非常耗費時間
而且非常復雜
通常需要高級的專門技術
確定是否是JIT問題
在某些情況下
從問題的特性可以很清楚地看出就是JIT的問題
例如
在JVM終止時帶有Javadump(在Linux上
Javadump的文件名的格式為javacore
YYYYMMDD
HHMMSS
PID
txt)或Linuxcore文件的情況下
從Javadump中的跟蹤信息或gdb對Java可執行文件和core文件的輸出信息中
可以很清楚地判斷出JIT就是產生問題的原因
在某些情況下
會直接顯示導致JVM進程死亡的信號是在libjitc
so中接收到的
在另外一些情況下
在JVM進程的代碼中
但是在該進程的已編譯代碼之外
會產生崩潰或掛起
這可以說明問題是由於JIT編譯的代碼產生的
然而
在大部分情況下
並沒有清晰的跡象表明JIT是否是問題的源頭
因此
給定JIT的重要性後
在問題判斷過程中的第一個步驟應該是禁用JIT
除非這顯然不是一個與JIT相關的問題
即使在有跡象表明JIT就是問題的原因的情況下
最好也通過禁用JIT進行一下驗證
並重新運行一下禁用了JIT的程序
要禁用JIT
首先請檢查一下當前環境變量JAVA_COMPILER的設置
然後將其設置為NONE
例如
對於BourneAgainShell(bash)或Kornshell(ksh)
設置如下
exportJAVA_COMPILER=NONE
對於csh
設置如下
setenvJAVA_COMPILERNONE 另外一種禁用JIT的方法是向java命令傳遞
D參數
將piler設置為NONE
從而覆蓋默認的環境變量置
piler=NONE<myapp> JIT默認是被啟用的
要驗證JIT是否被啟用了
可以使用java命令的
version選項
java
version
如果沒有啟用JIT
就會顯示一個包含如下內容的消息
JITdisabled 如果啟用了JIT
就會顯示一個包含如下內容的消息
JITenabled:jitc 如果指定了JAVA_COMPILER=
或piler=
那就禁用了JIT
如果JAVA_COMPILER沒有設置
如下
unsetJAVA_COMPILER 那麼JIT編譯器就啟用了
再次運行一下程序
看一下禁用JIT之後問題是否重現
如果問題可以重現
那麼這就不是一個與JIT有關的問題
如果在禁用JIT之後問題就不存在了
那麼這就可能是一個與JIT有關的問題
在禁用JIT之後問題就不再出現的現象並不意味著JIT編譯器就是問題的原因
例如
高度線程化且時間相關的程序中的方法在編譯後和解釋時的運行速度可能會不同
因此Java代碼中的邏輯錯誤只會在編譯代碼之後才會出現
要啟用JIT
請將JAVA_COMPILER設置為jitc
或者使用下面的命令行來切換JIT編譯器
piler=jitc<myapp> 或者取消JAVA_COMPILER環境變量的設置
或者從傳遞給java命令的選項中刪除piler選項
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26875.html