當前位置:
首頁 > 知識 > 輕鬆學JVM(一)——基本原理

輕鬆學JVM(一)——基本原理


前言

JVM一直是java知識裡面進階階段的重要部分,如果希望在java領域研究的更深入,則JVM則是如論如何也避開不了的話題,本系列試圖通過簡潔易讀的方式,講解JVM必要的知識點。


運行流程

我們都知道java一直宣傳的口號是:一次編譯,到處運行。那麼它如何實現的呢?我們看下圖:

輕鬆學JVM(一)——基本原理

java程序經過一次編譯之後,將java代碼編譯為位元組碼也就是class文件,然後在不同的操作系統上依靠不同的java虛擬機進行解釋,最後再轉換為不同平台的機器碼,最終得到執行。這樣我們是不是可以推演,如果要在mac系統上運行,是不是只需要安裝mac java虛擬機就行了。那麼了解了這個基本原理後,我們嘗試去做更深的研究,一個普通的java程序它的執行流程到底是怎樣的呢?例如我們寫了一段這樣的代碼:

public class HelloWorld {

這段程序從編譯到運行,最終列印出「Hello world」中間經過了哪些步驟呢?我們直接上圖:

輕鬆學JVM(一)——基本原理

java代碼通過編譯之後生成位元組碼文件(class文件),通過:java HelloWorld執行,此時java根據系統版本找到jvm.cfg,各位可以搜索一下自己電腦上的jvm.cfg文件在哪,它會根據你的系統版本放在不同的位置,比如我的這個文件就在:C:Program FilesJavajdk1.8.0_101jrelibamd64jvm.cfg,打開看一下:

輕鬆學JVM(一)——基本原理

這是我電腦上的文件,其中-server KNOWN就表示名稱為server的jvm可用。如果這時你搜索一下你電腦上jvm.dll,你就會發現它一定在你的某個server目錄下,比如我的:C:Program FilesJavajdk1.8.0_101jreinserverjvm.dll。簡而言之就是通過jvm.cfg文件找到對應的jvm.dll,jvm.dll則是java虛擬機的主要實現。接下來會初始化JVM,並且獲取JNI介面,什麼是JNI介面,就是java本地介面,你想啊java被編譯成了class文件,JVM怎麼從硬碟上找到這個文件並裝載到JVM里呢,就是通過JNI介面(它還常用於java與操作系統、硬體交互),找到class文件後並裝載進JVM,然後找到main方法,最後執行。


JVM基本結構

可能通過上面的描述,大家對JVM運行流程有了一個粗略的認識,那麼JVM內部到底是怎麼執行一個class文件的呢,也就是上圖中最後一步第6步的內部細節是怎樣的呢?要了解這個問題,我們首先得看一下JVM的內部結構:

輕鬆學JVM(一)——基本原理

從這個結構不難看出,class文件被jvm裝載以後,經過jvm的內存空間調配,最終是由執行引擎完成class文件的執行。當然這個過程還有其他角色模塊的協助,這些模塊協同配合才能讓一個java程序成功的運行,下面就詳細介紹這些模板,它們也是後面學習jvm最重要的部分。

內存空間:

JVM內存空間包含:方法區、java堆、java棧、本地方法棧。

方法區是各個線程共享的區域,存放類信息、常量、靜態變數。

java堆也是線程共享的區域,我們的類的實例就放在這個區域,可以想像你的一個系統會產生很多實例,因此java堆的空間也是最大的。如果java堆空間不足了,程序會拋出OutOfMemoryError異常。

java棧是每個線程私有的區域,它的生命周期與線程相同,一個線程對應一個java棧,每執行一個方法就會往棧中壓入一個元素,這個元素叫「棧幀」,而棧幀中包括了方法中的局部變數、用於存放中間狀態值的操作棧,這裡面有很多細節,我們以後再講。如果java棧空間不足了,程序會拋出StackOverflowError異常,想一想什麼情況下會容易產生這個錯誤,對,遞歸,遞歸如果深度很深,就會執行大量的方法,方法越多java棧的佔用空間越大。

本地方法棧角色和java棧類似,只不過它是用來表示執行本地方法的,本地方法棧存放的方法調用本地方法介面,最終調用本地方法庫,實現與操作系統、硬體交互的目的。

PC寄存器,說到這裡我們的類已經載入了,實例對象、方法、靜態變數都去了自己改去的地方,那麼問題來了,程序該怎麼執行,哪個方法先執行,哪個方法後執行,這些指令執行的順序就是PC寄存器在管,它的作用就是控制程序指令的執行順序。

執行引擎當然就是根據PC寄存器調配的指令順序,依次執行程序指令。


結語

本文主要介紹了java虛擬機運行的基本流程,以及java虛擬機內部結構。下一篇我們將學習java內存模型以及探索java變數的可見性、有序性、指令重排等問題。


學習Java的同學注意了!!!

學習過程中遇到什麼問題或者想獲取學習資源的話,歡迎加入Java學習交流群495273252,我們一起學Java!

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Java團長 的精彩文章:

面試分享:一年經驗初探阿里巴巴前端社招
程序員的小目標:升職加薪
你知道么?static關鍵字有5種用法
關於面試!(面試篇)
溫水裡的程序員,技術將成為溫水——學習分享

TAG:Java團長 |

您可能感興趣

JVM系列(一)JVM啟動流程和基本結構
深入理解JVM—JVM內存模型
JVM內存分配、GC原理與垃圾收集器
JRE、JDK、JVM是什麼?
JVM學習系列學習一
JVM學習系列學習四
新一代開源分散式賬本項目R3 Corda 技術揭秘:基於JVM開發
JVM 之 ParNew 和 CMS 日誌分析
大神教你JVM運行原理及Stack和Heap的實現過程
使用 JITWatch 查看 JVM 的 JIT 編譯代碼
JVM學習系列學習二
JVM學習系列學習六
一文讀懂JVM 與 Linux 的內存關係
JVM學習系列學習三
阿里P8架構師談:資料庫、JVM、緩存、SQL等性能調優方法和原則
是否值得付費?Oracle,Open JDK等四大JVM性能全面對比
JVM和Python解釋器的硬碟夜話
深入談談String.intern在JVM的實現
Try-catch-finally在JVM底層都幹了些啥?
關於 JVM 內存的 N 個問題