关于HotSpot VM以及Java语言的动态编译 你可能想知道这些
目錄
- 1 HotSpot VM的歷史
- 2 HotSpot VM 概述
- 2.1 編譯器
- 2.2 解釋器
- 2.3 解釋型語言 VS 編譯型語言
- 3 動態編譯
- 3.1 什么是動態編譯
- 3.2 HotSpot VM對字節碼的處理方式
- 3.3 為什么不靜態編譯
1 HotSpot VM的歷史
SUN/Oracle JDK中使用的JVM是HotSpot VM.
SUN JDK從1.3.1版本開始采用HotSpot虛擬機, 并于2006年底開源, 主要使用C++實現, JNI接口部分用C實現.
HotSpot是比較新的JVM, 用來替代JIT (Just in Time, 即時編譯), 可以大大提高Java的運行性能 —— 通過下述方法提高性能:
Java起初是將源代碼編譯class字節碼在虛擬機上執行, 速度較慢;
HotSpot將常用的部分代碼編譯為本地(native)代碼, 顯著提高性能.
HotSpot JVM參數分為標準參數(standard options)、非標準參數(non-standard options) 以及非穩定參數, 可參考: 關于JVM的垃圾回收(GC) 這可能是你想了解的 中4.1 參數名稱的說明.
2 HotSpot VM 概述
HotSpot包括一個解釋器和兩個編譯器(client和server, 實際運行中選擇其一即可, 大多選擇server), 解釋與編譯混合執行模式, 默認啟動解釋執行.
① server模式下應用程序啟動較慢, 占用內存多, 但執行效率高, 其適用于服務器端需要長期執行的應用;
② client模式下應用程序啟動較快, 占用內存小, 但執行效率較低, 默認情況下不進行動態編譯, 適用于桌面應用程序.
(1) 查看 JVM 的啟動模式:
# 使用解釋與編譯混合的模式 java -version java version "1.8.0_162" Java(TM) SE Runtime Environment (build 1.8.0_162-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode) # mixed mode 解釋與編譯混合的模式, 是默認使用的模式. # 使用純解釋模式 java -Xint -version java version "1.8.0_162" Java(TM) SE Runtime Environment (build 1.8.0_162-b12) # interpreted mode 純解釋模式, 即禁用JIT編譯. # 使用純編譯模式 java -Xcomp -version java version "1.8.0_162" Java(TM) SE Runtime Environment (build 1.8.0_162-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, compiled mode) # compiled mode 純編譯模式, 如果方法無法編譯, 則回退到解釋模式執行無法編譯的方法.2.1 編譯器
Java源代碼被編譯器編譯成class字節碼文件, 字節碼在運行時可以被動態編譯(JIT)成本地代碼, 前提是解釋與編譯混合執行模式且虛擬機不是剛啟動.
2.2 解釋器
解釋器用來解釋class字節碼文件, Java是解釋型語言(區別于編譯型語言).
2.3 解釋型語言 VS 編譯型語言
計算機不能直接理解執行高級語言, 只能直接執行機器語言, 所以必須將高級語言翻譯成機器語言再執行.
翻譯的方式有兩種 —— 編譯和解釋, 兩者只是翻譯的時間不同:
① 解釋型語言: 不需要提前翻譯 —— 例如Java語言, 在運行時才翻譯, 再由專門的解釋器解釋執行 —— 每執行一次就要翻譯一次, 效率較低.
優點: 可移植性好, 只要有解釋環境, 就可以在不同的操作系統上運行. 比如在解釋執行時可以動態改變變量的類型、修改程序以及在程序中插入良好的調試診斷等信息, 將解釋器移植到不同的系統上,則程序不用改動就可以在移植了解釋器的系統上運行。
缺點: 運行需要解釋環境, 運行速度較慢, 占用的資源更多 —— 因為不僅要為用戶程序分配空間, 解釋器本身也要占用一定的系統資源. 其封裝了底層代碼, 程序嚴重依賴平臺, 不能同C++那樣直接操作底層.
代表: 一些網頁腳本、服務器腳本等對速度要求不高, 卻對不同系統平臺間的兼容性有要求的程序通常使用解釋性語言, 如Java、JavaScript、Perl、Python、Ruby、MATLAB等.
② 編譯型語言: 編寫的程序在運行前, 需要通過編譯器將代碼編譯成機器語言(二進制文件), 然后直接由相應的操作系統執行.
編譯和執行是分開的, 但不能跨平臺. 例如 C++ 編譯成的 exe 文件, 運行時不需再次編譯, 直接使用編譯的結果即可 —— 效率較高.
因為不同的操作系統識別的二進制文件是不同的, 所以編譯型語言的程序在移植后, 需要重新編譯(如Windows下的C程序編譯成exe文件, Linux下要編譯成erp文件).
優點: 運行速度快, 代碼效率高, 同等條件下對系統要求較低.
缺點: 代碼需要經過編譯才能運行, 可移植性差 —— 只能在兼容的操作系統上運行.
代表: 像開發操作系統、大型應用程序、數據庫系統等時都使用編譯型語言, 如C、C++、Pascal等.
3 動態編譯
3.1 什么是動態編譯
動態編譯 (compile during run-time), 英文稱 Dynamic compilation, Just In Time (即時編譯) 也有此意.
HotSpot VM對字節碼的編譯不是在程序運行前, 而是在程序運行過程中編譯的.
HotSpot VM中有一個監視器 (Profile Monitor), 用來監視程序的運行狀況.
Java字節碼 (class文件) 是以解釋的方式被加載到虛擬機中 (默認啟動時就解釋執行), 程序運行過程中, 使用頻率高、對程序的性能影響重要的代碼, 稱之為熱點 (hotspot), HotSpot VM會把這些熱點動態地編譯成機器碼 (native code), 同時對機器碼進行優化, 從而提高運行效率. 對使用頻率較低的代碼, HotSpot VM就不會編譯.
比如指令的重排序, 使用volatile關鍵字可以禁止重排序等類似的操作都是在這個編譯階段進行的.
3.2 HotSpot VM對字節碼的處理方式
① 不編譯: 字節碼加載到虛擬機中時的狀態, 也就是虛擬機執行時再編譯;
② 編譯: 把字節碼編譯成本地代碼, 虛擬機執行時已經編譯好了, 無需再次編譯;
③ 編譯并優化: 不但把字節碼編譯成本地代碼, 而且還進行了優化.
具體如何處理, 都是由監視器 (Profile Monitor) 決定的.
3.3 為什么不靜態編譯
為什么不采取將字節碼直接變異成本地代碼, 然后再裝載到虛擬機中?
① 動態編譯器在許多方面比靜態編譯器優越 —— 靜態編譯器通常很難預知程序運行過程中最需要優化的代碼.
② 函數調用是很浪費系統時間的, 因為有許多進出棧操作. 因此有一種優化辦法, 就是把原來的函數調用通過編譯, 改為非函數調用 —— 將函數代碼直接嵌到調用的地方, 變為順序執行.
③ 面向對象的語言支持多態, 靜態編譯無法確定程序調用的到底是超類的哪些實現子類的方法, 因為多態是在程序運行中才能具體確定的.
參考資料
OpenJDK和Sun/OracleJDK 區別 與聯系
【Language】解釋性語言和編譯型語言的區別和不同
版權聲明
作者: 馬瘦風
出處: 博客園 馬瘦風的博客
您的支持是對博主的極大鼓勵, 感謝您的閱讀.
本文版權歸博主所有, 歡迎轉載, 但請保留此段聲明, 并在文章頁面明顯位置給出原文鏈接, 否則博主保留追究相關人員法律責任的權利.
轉載于:https://www.cnblogs.com/shoufeng/p/9736148.html
總結
以上是生活随笔為你收集整理的关于HotSpot VM以及Java语言的动态编译 你可能想知道这些的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ubuntu-server-18.04
- 下一篇: Java基础(三)选择和循环结构