JVM學習(一)初識JVM

相信每一個學習JAVA的同行都聽說過JVM,但是真正懂JVM的人卻寥寥無幾。對於初學java的人來說可能不會涉及到JVM的知識,隨着學習的不斷深入,我們就會時常聽到JVM調優,垃圾回收算法等等一系列關於JVM的概念,勾起我們對JVM學習的慾望,正當我們充滿激情地尋找資料誓要弄清JVM的時候,迎來的卻是當頭一棒,因爲JVM確實是太難學了,網上很多大神寫的博客,以及暢銷的相關書籍門檻很高,很多人第一次看就放棄了,不知多久之後才回過來再去學習。在接下來的時間裏,我將和廣大同行們一起揭開JVM的神祕面紗。這是筆者有關JVM的第一篇博客,通過此篇博客你將對JVM有個初步的認識,希望勾起你對JVM學習的渴望

什麼是JVM

在回答這個問題之前我認爲我們更應該先來說一說我們寫好的java代碼是如何被計算機執行的?這聽起來可能是不符合邏輯,但是這可以讓我們更好更系統地理解JVM,而不會讓我們對JVM 的理解僅僅侷限於它是運行java的平臺而已。
Java 代碼有很多種不同的運行方式。比如說可以在開發工具中運行,可以雙擊執行 jar 文件運行,也可以在命令行中運行,甚至可以在網頁中運行。當然,這些執行方式都離不開 JRE,也就是 Java 運行時環境。JRE由Java API和JVM組成,JVM通過類加載器(Class Loader)加類Java應用,並通過Java API進行執行。
首先java文件會被JVM編譯爲字節碼文件(之所以這麼取名,是因爲 Java 字節碼指令的操作碼(opcode)被固定爲一個字節),也就是我們常說的class文件,java字節碼不能被計算機所讀懂,它是給JVM來運行的。Java 虛擬機需要將字節碼翻譯(解釋執行或者編譯)成機器碼,這樣計算機就可以執行了
下面以標準 JDK 中的 HotSpot 虛擬機爲例,從虛擬機以及底層硬件兩個角度,講一講 Java 虛擬機具體是怎麼運行 Java 字節碼的。從虛擬機視角來看,執行 Java 代碼首先需要將它編譯而成的 class 文件加載到 Java 虛擬機中。加載後的 Java 類會被存放於方法區(Method Area)中。實際運行時,虛擬機會執行方法區內的代碼。Java 虛擬機在內存中劃分出堆和棧來存儲運行時數據。棧細分爲面向 Java 方法的 Java 方法棧,面向本地方法(用 C++ 寫的 native 方法)的本地方法棧,以及存放各個線程執行位置的 PC 寄存器。
在這裏插入圖片描述
在運行過程中,每當調用進入一個 Java 方法,Java 虛擬機會在當前線程的 Java 方法棧中生成一個棧幀,用以存放局部變量以及字節碼的操作數。這個棧幀的大小是提前計算好的,而且 Java 虛擬機不要求棧幀在內存空間裏連續分佈。當退出當前執行的方法時,不管是正常返回還是異常返回,Java 虛擬機均會彈出當前線程的當前棧幀,並將之捨棄。從硬件視角來看,Java 字節碼無法直接執行。因此,Java 虛擬機需要將字節碼翻譯成機器碼。在 HotSpot 裏面,上述翻譯過程有兩種形式:第一種是解釋執行,即逐條將字節碼翻譯成機器碼並執行;第二種是即時編譯(Just-In-Time compilation,JIT),即將一個方法中包含的所有字節碼編譯成機器碼後再執行。前者的優勢在於無需等待編譯,而後者的優勢在於實際運行速度更快。HotSpot 默認採用混合模式,綜合瞭解釋執行和即時編譯兩者的優點。它會先解釋執行字節碼,而後將其中反覆執行的熱點代碼,以方法爲單位進行即時編譯。爲了提高運行效率,標準 JDK 中的 HotSpot 虛擬機採用的是一種混合執行的策略。

現在再來解釋一下什麼是Java虛擬機

Java虛擬機就是運行java字節碼的一個平臺,java類的加載以及方法的執行與銷燬都需要經過Java虛擬機。Java 虛擬機可以由硬件實現,但更爲常見的是在各個現有平臺(如 Windows_x64、Linux_aarch64)上提供軟件實現。這麼做的意義在於,一旦一個程序被轉換成 Java 字節碼,那麼它便可以在不同平臺上的虛擬機實現裏運行。這也就是我們經常說的“一次編寫,到處運行”。虛擬機帶來了一個託管環境(Managed Runtime)。這個託管環境能夠代替我們處理一些代碼中冗長而且容易出錯的部分。其中最廣爲人知的當屬自動內存管理與垃圾回收。除此之外,託管環境還提供了諸如數組越界、動態類型、安全權限等等的動態檢測,使我們免於書寫這些無關業務邏輯的代碼。

爲什麼要學習JVM

  • Java 虛擬機提供了許多配置參數,用於滿足不同應用場景下,對程序性能的需求。學習 Java 虛擬機,你可以針對自己的應用,最優化匹配運行參數。
  • Java 虛擬機本身是一種工程產品,在實現過程中自然存在不少侷限性。學習 Java 虛擬機,可以更好地規避它在使用中的 Bug,也可以更快地識別出 Java 虛擬機中的錯誤。
  • Java 虛擬機擁有當前最前沿、最成熟的垃圾回收算法實現,以及即時編譯器實現。學習 Java 虛擬機,我們可以瞭解背後的設計決策,今後再遇到其他代碼託管技術也能觸類旁通。
  • Java 虛擬機發展到了今天,已經脫離 Java 語言,形成了一套相對獨立的、高性能的執行方案。除了 Java 外,Scala、Clojure、Groovy,以及時下熱門的 Kotlin,這些語言都可以運行在 Java 虛擬機之上。學習 Java 虛擬機,便可以瞭解這些語言的通用機制,甚至於讓這些語言共享生態系統。
  • 學習 Java 虛擬機的本質,更多是瞭解 Java 程序是如何被執行且優化的。這樣一來,你纔可以從內部入手,達到高效編程的目的。與此同時,你也可以爲學習更深層級、更爲核心的 Java 技術打好基礎。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章