天天看點

【深入了解JVM】JVM的記憶體結構(堆、棧、GC)Java跨平台什麼是JVM?JVM的組成運作時資料區

文章目錄

  • Java跨平台
  • 什麼是JVM?
  • JVM的組成
  • 運作時資料區
      • 棧幀中的動态連結
    • 本地方法棧
    • 執行引擎
    • 堆和Full GC
    • 堆、棧、方法區的愛恨糾葛

  最近一直在看JVM相關的東西,在這裡整理一下,友善以後複盤,有錯誤的地方歡迎留言。

Java跨平台

  不同作業系統使用的指令不同,JVM 可以将位元組碼翻譯成特定平台下的機器碼運作,在不同平台安裝對應的 JVM,就可以運作位元組碼,通過 JVM 這一“中間層”屏蔽了作業系統的差異,不同 JDK 适應不同的作業系統,使Java具有跨平台的特性。

什麼是JVM?

   JVM 即 Java Virtual Machine(Java虛拟機) , 模拟一個計算機來達到計算機所具有的計算功能。屏蔽各計算機硬體和軟體之間的差異,使位元組碼檔案可以“到處運作”。

JVM的組成

JVM由四部分組成:

  • 類加載器
  • 運作時資料區
  • 執行引擎
  • 本地接口

運作時資料區

   由 堆、棧、程式計數器、本地方法棧、方法區 五部分組成。

【深入了解JVM】JVM的記憶體結構(堆、棧、GC)Java跨平台什麼是JVM?JVM的組成運作時資料區
【深入了解JVM】JVM的記憶體結構(堆、棧、GC)Java跨平台什麼是JVM?JVM的組成運作時資料區

由線程共享

【深入了解JVM】JVM的記憶體結構(堆、棧、GC)Java跨平台什麼是JVM?JVM的組成運作時資料區

由線程獨有,每個線程都包含 棧、程式計數器、本地方法棧。

【深入了解JVM】JVM的記憶體結構(堆、棧、GC)Java跨平台什麼是JVM?JVM的組成運作時資料區

線程中每執行一個方法,棧中進入一個棧幀,棧幀由四部分組成。

  • 局部變量表
  • 操作數棧
  • 動态連結
  • 方法出口
public class Test{
    public static void main(String[] args){
         int i = 1;
         int j = 2;
         int k = i + j;
         System.out.println(k);
    }
}
           

由Test.java說明程式運作時棧中情況。

javac Test.java 編譯成Test.class。

javap -c Test.class>Test.txt 将位元組碼反編譯結果輸出到Test.txt檔案中,内容如下:

Compiled from “Test.java”

public class Test {

public Test();

Code:

0: aload_0

1: invokespecial #1 // Method java/lang/Object.""😦)V

4: return

public static void main(java.lang.String[]);

Code:

0: iconst_1

1: istore_1

2: iconst_2

3: istore_2

4: iload_1

5: iload_2

6: iadd

7: istore_3

8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;

11: iload_3

12: invokevirtual #3 // Method java/io/PrintStream.println:(I)V

15: return

}

可以去下列網址檢視 iconst_1 JVM位元組碼指令的含義

https://www.cnblogs.com/tenghoo/p/jvm_opcodejvm.html

大緻意思:

  把1放入操作數棧,将1賦給變量 i 存入局部變量,j 同理,将1和2相加為3再賦給變量k。

  程式計數器會記錄将要執行的指令行号,這樣在挂起後恢複等操作時就可以知道上次執行的位置。

棧幀中的動态連結

這就要說一下靜态連結,在類加載過程中包含如下步驟:

【深入了解JVM】JVM的記憶體結構(堆、棧、GC)Java跨平台什麼是JVM?JVM的組成運作時資料區

  靜态連結在類加載過程中的解析階段進行,将部分符号引用轉為直接引用,位元組碼符号無法直接使用,直接引用類似于位址,這樣才可以使用。

  動态連結是在運作時将符号引用轉為直接引用。

  方法出口可以了解為方法的 return。

本地方法棧

  在Java之前使用C的很多,Java有些也是用C實作的,Java中也有 native修飾的方法,這樣的方法就是用C實作的,這些字元存在本地方法棧中,執行引擎會找C語言的函數庫(.dll)。

執行引擎

執行引擎執行位元組碼的方式:

  • 解釋執行:一行一行邊翻譯邊執行
  • JIT即時編譯執行:這裡有熱點代碼的概念,被多次調用的方法或被多次執行的循環體視為熱點代碼,熱點代碼會被編譯執行,這樣效率高點

堆和Full GC

【深入了解JVM】JVM的記憶體結構(堆、棧、GC)Java跨平台什麼是JVM?JVM的組成運作時資料區

堆 由年輕代、老年代組成。在JVM啟動時建立,是GC垃圾回收的主要對象,也是配置設定存儲區最大的一塊。

年輕代 由Eden區(伊甸區)、From Survivor、To Survivor組成。

這裡需要說一下輕GC(Minor gc)和Full GC。

  • 新建立的對象需要放入Eden區,當Eden區滿後,GC回收沒有被引用的對象,剩餘對象放到From Survivor區;
  • 當From Survivor區滿後,清空From Survivor區,未被回收的對象放入To Survivor區;
  • 此時From和To身份互換,From變為To,To變為From,如此循環15次(預設15次),當To區滿時,将未被清理的對象放入老年代;
  • 當老年代滿時,觸發Full GC(之前都是Minor GC),由于不同的垃圾回收器機制不同,可能把之前的區都清理,也可能隻清理老年區(涉及到垃圾回收器和算法,以後再寫一篇補上)。

堆、棧、方法區的愛恨糾葛

【深入了解JVM】JVM的記憶體結構(堆、棧、GC)Java跨平台什麼是JVM?JVM的組成運作時資料區

   s 學生變量存在棧中,在堆中建立對象,将對象的位址賦給s變量;

堆中的對象執行個體指向方法區的類模闆,通過類模闆建立執行個體對象。

下一篇: 從大到小

繼續閱讀