1. 程式人生 > >深入JVM(二)JVM概述

深入JVM(二)JVM概述

  1. 深入JVM(一)JVM指令手冊
  2. 深入JVM(二)JVM概述

一.JVM的原理

Java虛擬機器是Java平臺的基石,解決了硬體和作業系統的相互獨立性。不同平臺(Windows,Linux和MacOS)的JVM都是不同的,但是他們都提供了相同的介面。虛擬機器可以分為系統虛擬機器和程式虛擬機器。系統虛擬機器就是VMware和VirtualBox這一類的,完全是對物理資源的隔離。而Java虛擬機器是程式虛擬機器,它包含了一組指令集並在執行時操作各個不同記憶體區域,這些指令在JVM中稱為Java位元組碼指令。

 

二.JVM的結構

JVM的基本結構如下圖所示:

 

圖中的Java檔案泛指所有構建在Java虛擬機器上的程式語言檔案,如Groovy, Scala, Kotlin等。JVM不和上述任何語言關聯,而是使用javac把這些語言編譯為“Class檔案”的這種二進位制格式。Class檔案中包含了JVM指令集和符號表已經其他一些資訊。

2.1 類載入子系統

負責從class位元組碼檔案中並存放在方法區的記憶體中,並對資料進行校驗,轉換解析和初始化,最終形成可以被虛擬機器直接使用的Java型別。

2.2 執行引擎

負責執行虛擬機器的位元組碼,JVM制定了自己的指令集和體系結構,輸入位元組碼檔案並輸出執行結果。

2.3 程式計數器

是一塊較小的記憶體空間,可以看做是當前執行緒所執行的位元組碼行號指示器,每個執行緒都有一個獨立的程式計數器。在虛擬機器概念模型中,位元組碼直譯器工作時就是通過改變計數器的值來選取下一條待執行的指令。當發生CPU時間片切換的時候,由程式計數器來確保當執行緒重新獲取到CPU時間片後能夠恢復到正確的執行位置。
如果當前方法是Java方法,程式計數器的值是正在執行的虛擬機器位元組碼指令地址;如果是Native方法,則為空

2.4 虛擬機器棧

是執行緒私有的,並與執行緒的生命週期相同。虛擬機器棧中又會包含多個棧幀,每執行一個方法就建立一個棧幀,用於儲存區域性變量表、操作棧、方法返回值等。每一個方法從呼叫直至執行完成的過程,就對應一個棧幀在java棧中入棧到出棧的過程。

其中的區域性變量表存放了各種基本資料型別,物件引用地址和returnAddress。所以區域性變量表所需要的記憶體空間在編譯期就可以完成分配。當進入到一個方法的時候,該方法所需要在棧幀中的大小是確定的,並且在執行期間不會改變

2.5 本地方法棧

本地方法棧的作用類似於虛擬機器棧,只不過虛擬機器棧是為執行Java方法服務,而本地方法棧則為虛擬機器使用到的native方法服務

2.6 堆

堆在虛擬機器啟動的時候建立,是被所有執行緒共享的一塊記憶體區域。幾乎所有的物件都放在堆上,堆也就成為了垃圾回收的主要區域。在JDK1.8之前,堆可以分為新生代和老年代,其中新生代又可以細分為Eden,From和To三塊區域。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

從JDK1.8開始,永久代從堆記憶體中被轉移到本地記憶體中

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2.7 方法區

各個執行緒共享的記憶體區域,用於儲存已經被載入的類資訊、常量、靜態變數、及時編譯器編譯後的程式碼等。在HotSpot虛擬機器上方法區就對應上圖中的永久代。該區域不需要連續的記憶體區域,GC回收的主要目標是針對常量池和型別的解除安裝。