目錄
?
一、什么是JVM(Java虛擬機)?
二、JVM的功能
三、JVM的功能-即時編譯?
四、常見的JVM
五、JVM的組成
五、JVM的工作流程
????????參考資料
一、什么是JVM(Java虛擬機)?
在Java的世界里,Java虛擬機(JVM)扮演著至關重要的角色。它不僅是Java程序運行的環境,更是實現“一次編寫,到處運行”的關鍵。本文將深入探討JVM的核心組成部分,從類加載到執行引擎,解開JVM神秘的面紗。
?JVM本質上是一個運行在計算機上的程序,他的職責是運行Java字節碼文件。
JVM,即Java虛擬機,是一個用于執行Java字節碼的虛擬計算機。它是在硬件或操作系統上構建的一個軟件層,使Java字節碼可以在不同的平臺上運行。即時編譯(Just-In-Time compilation)是JVM的一個關鍵功能,它允許JVM在運行時將字節碼編譯成本地代碼,以提高程序的性能。
即時編譯的主要功能如下:
- 預編譯(Compile-Ahead-Of-Time):JVM首先將Java源代碼編譯成字節碼,然后這些字節碼在運行時被即時編譯成本地代碼。這種預編譯的方式使得程序在第一次運行時不需要進行編譯,從而提高了程序的啟動速度。
- 熱點代碼優化:JVM通過熱點代碼優化技術來提高程序的運行效率。熱點代碼是指被頻繁執行的代碼。JVM在運行時收集這些熱點代碼的執行信息,并將它們編譯成更高效的本地代碼。這種優化可以顯著提高程序的性能,特別是對于那些頻繁運行的代碼。
- 動態編譯:即時編譯還支持動態編譯。這意味著JVM可以根據程序在運行時的行為動態地調整編譯策略。例如,如果某個方法沒有被頻繁調用,那么JVM可以暫時不將其編譯成本地代碼,以節省資源。相反,如果某個方法被頻繁調用,JVM可以將其優先編譯成本地代碼,以提高程序的運行效率。
- 內存管理和垃圾回收:JVM還提供了內存管理和垃圾回收的功能。這些功能可以幫助程序員更好地管理內存資源,并提高程序的可靠性。
總之,即時編譯是JVM的一個重要功能,它可以幫助程序員提高程序的性能和可靠性。通過將Java字節碼編譯成本地代碼,JVM可以減少解釋字節碼所需的時間,從而提高程序的執行速度。同時,即時編譯還可以根據程序在運行時的行為動態地調整編譯策略,以進一步提高程序的性能。
?將字節碼文件轉換成計算機可以看懂的機器碼文件。這就是Java虛擬機的主要功能。
二、JVM的功能
三、JVM的功能-即時編譯?
?JVM可以將熱點的代碼字節指令,保存到內存中,等到再次執行時可以直接調用。
四、常見的JVM
常見的JVM包括HotSpot、JRockit、J9等。
HotSpot是較新的Java虛擬機技術,用來代替JIT(just-in-time compilation,及時編譯)技術,可以大大提高Java運行的性能。HotSpot將常用的部分代碼編譯為本地(原生,native)代碼,這樣顯著提高了性能。它從運行應用中采樣數據,從而可以優化代碼,進而得到良好性能。HotSpot引擎可以集中精力來對HotSpot代碼進行深度優化,從而使這部分代碼的執行更加迅捷。但它的啟動時間較長。
JRockit是BEA公司開發的,可以直接運行在自家Hypervisor系統上的JRockit VM的虛擬化版本,JRockit VM不需要操作系統的支持,或者說它自己本身實現了一個專用操作系統的必要功能,如文件系統、網絡支持等。
IBM J9是IBM開發的Java虛擬機,它也支持即時編譯技術。
我們開發時,基本都會優先選擇使用HotSpot。?
五、JVM的組成
JVM主要組成有四個子系統組成:類加載系統、運行時數據區域、執行引擎、本地方法接口。
?
-
類加載系統(Class Loading System):
- 加載(Loading): 加載是指查找字節碼文件,并創建一個Class對象的過程。字節碼文件通常由Java編譯器從Java源代碼生成。
- 驗證(Verification): 確保字節碼文件符合Java語言規范,并且不包含不安全或非法的代碼。
- 準備(Preparation): 為類的靜態變量分配內存并設置默認初始值。
- 解析(Resolution): 將常量池中的符號引用替換為直接引用,使得各個類之間能夠正確地引用。
-
執行引擎(Execution Engine):
- 解釋器(Interpreter): 將字節碼文件逐行解釋為機器碼并執行。
- 即時編譯器(Just-In-Time Compiler,JIT): 將整個字節碼文件編譯為機器碼,提高執行速度。
- 棧操作(Stack Operations): 使用操作棧進行方法調用、參數傳遞等。
-
本地方法接口(Native Interface):
- 允許Java應用程序調用本地方法(通常使用C或C++編寫的代碼)。Java的本地方法接口允許Java代碼與本地庫進行交互,實現了Java與其他語言的銜接。JVM通過本地庫接口與操作系統提供的庫進行交互,保證了Java程序的可移植性。
-
運行時數據區域(Runtime Data Area):
- 方法區(Method Area): 存儲類的結構信息,如類的字段、方法信息。
- 堆(Heap): 存儲對象實例,包括程序運行時創建的對象。
- 棧(Stack): 存儲局部變量、方法調用和返回地址。
- 程序計數器(Program Counter): 記錄當前線程執行的字節碼行號。
- 本地方法棧(Native Method Stack): 執行本地方法時使用的棧。
Java程序能夠在不同平臺上實現“一次編寫,到處運行”的特性。類加載系統負責加載和驗證Java類,執行引擎負責執行Java代碼,本地方法接口提供了與底層系統的交互能力,而運行時數據區域存儲程序執行時的數據。JVM通過本地庫接口與操作系統提供的庫進行交互,保證了Java程序的可移植性。
以上圖來源于黑馬課件?
此圖來源于《深入理解Java虛擬機》?
五、JVM的工作流程
JVM的工作流程通常包括以下幾個步驟:
- 加載(Loading)
加載階段是JVM啟動的第一個階段,它負責從系統中加載Java類和接口的定義信息。加載階段的主要任務是找到并加載Java類和接口的定義信息,并將其存儲在內存中。這些定義信息包括類的成員變量、成員方法、構造函數等。在加載階段,JVM還會對類的定義信息進行驗證,以確保其符合Java語言的規范。 - 鏈接(Linking)
鏈接階段是加載階段的后續階段,它負責驗證類的定義信息、為類的成員變量分配內存并設置默認值,以及解析類的符號引用。在鏈接階段,JVM會對類進行一系列的驗證,以確保其符合Java語言的規范。如果驗證不通過,則會拋出異常。此外,鏈接階段還會為類的成員變量分配內存并設置默認值,以及解析類的符號引用。符號引用是指用符號來引用類、方法、變量等的一種方式。 - 初始化(Initialization)
初始化階段是鏈接階段的后續階段,它負責執行類的初始化代碼。初始化階段的主要任務是執行類的初始化代碼,包括靜態初始化塊和靜態初始化方法。在初始化階段,JVM會執行類的靜態代碼塊和靜態變量的初始化代碼。如果存在多個靜態變量或靜態代碼塊,則會按照它們在類中的順序依次執行。 - 執行(Execution)
執行階段是JVM的核心階段,它負責執行Java程序的字節碼指令。執行階段的主要任務是執行Java程序的字節碼指令,包括對成員變量的讀寫操作、方法的調用等。在執行階段,JVM會根據程序的指令逐條執行字節碼指令,從而實現Java程序的運行。 - 卸載(Unloading)
卸載階段是JVM的最后一個階段,它負責卸載不再被使用的Java類和接口的定義信息。卸載階段的主要任務是回收被卸載的類占用的內存空間,以便重新被使用。在卸載階段,JVM會回收被卸載的類占用的內存空間,以便重新被使用。
以上就是JVM的基本工作流程,不同的JVM實現可能會有一些差異,比如內存分配策略、垃圾收集器類型等。
深入了解Java虛擬機,我們不僅能夠更好地理解Java程序的運行機制,還能夠優化程序性能、解決內存泄漏等問題。JVM的神秘面紗下,是一個復雜而高效的執行環境,為Java的成功貢獻著重要的力量。讓我們在編寫Java程序的同時,更加深入地認識JVM,為程序的優化和調優提供更多的可能性。
參考資料
- The Java? Virtual Machine Specification
- 深入理解Java虛擬機(第三版)