天天看點

JVM知識點整理(1)-JVM記憶體區域

注意: 

  GC:垃圾收集器

  Minor GC:新生代GC,指發生在新生代的垃圾收集動作

  Major GC/Full GC:老年代GC,指發生在老年代的GC。

  JVM:Java Virtual Machine(Java虛拟機)的縮寫。

基本概念:

  JVM是可運作Java 代碼的假想計算機 ,包括一套位元組碼指令集、一組寄存器、一個棧、一個垃圾回收,堆 和 一個存儲方法域。

  JVM 是運作在作業系統之上的,它與硬體沒有直接的互動。

  

JVM知識點整理(1)-JVM記憶體區域

運作過程:

  Java 源檔案,通過編譯器,能夠生産相應的.Class 檔案,也就是位元組碼檔案, 而位元組碼檔案又通過Java 虛拟機中的解釋器, 編譯成特定機器上的機器碼 。

  也就是如下:

    ①.Java 源檔案—->編譯器—->位元組碼檔案

    ②. 位元組碼檔案—->JVM—->機器碼

    每一種平台的解釋器是不同的,但是實作的虛拟機是相同的,這也就是Java 為什麼能夠跨平台的原因了。

    當一個程式從開始運作,這時虛拟機就開始執行個體化了,多個程式啟動就會存在多個虛拟機執行個體。

    程式退出或者關閉,則虛拟機執行個體消亡,多個虛拟機執行個體之間資料不能共享。

  

JVM知識點整理(1)-JVM記憶體區域

 線程:

  這裡所說的線程指程式執行過程中的一個線程實體。JVM 允許一個應用并發執行多個線程。Hotspot JVM 中的 Java 線程與原生作業系統線程有直接的映射關系。

  當線程本地存儲、緩沖區配置設定、同步對象、棧、程式計數器等準備好以後,就會建立一個作業系統原生線程。Java 線程結束,原生線程随之被回收。

  作業系統負責排程所有線程,并把它們配置設定到任何可用的 CPU 上。當原生線程初始化完畢,就會調用 Java 線程的 run() 方法。

  當線程結束時,會釋放原生線程和 Java 線程的所有資源。

JVM記憶體區域:

JVM知識點整理(1)-JVM記憶體區域

   JVM 記憶體區域主要分為線程私有區域【程式計數器、虛拟機棧、本地方法區】、線程共享區域【JAVA 堆、方法區】、直接記憶體。

    線程私有資料區域生命周期與線程相同, 依賴使用者線程的啟動/結束 而 建立/銷毀

注意: 在Hotspot VM 内, 每個線程都與作業系統的本地線程直接映射, 是以這部分記憶體區域的存/否跟随本地線程的生/死對應

    線程共享區域随虛拟機的啟動/關閉而建立/銷毀。

    直接記憶體并不是JVM運作時資料區的一部分,但也會被頻繁的使用: 例如在JDK 1.4 引入的NIO。

  

JVM知識點整理(1)-JVM記憶體區域

程式計數器(私有線程):

  一塊較小的記憶體空間, 是目前線程所執行的位元組碼的行号訓示器,每條線程都要有一個獨立的程式計數器,這類記憶體也稱為“線程私有”的記憶體。

  正在執行java 方法的話,計數器記錄的是虛拟機位元組碼指令的位址(目前指令的位址)。如果還是Native 方法,則為空。

這個記憶體區域是唯一一個在虛拟機中沒有規定任何OutOfMemoryError 情況的區域。

虛拟機棧(線程私有):

  是描述java 方法執行的記憶體模型,每個方法在執行的同時都會建立一個棧幀(Stack Frame)用于存儲局部變量表、操作數棧、動态連結、方法出口等資訊。

  每一個方法從調用直至執行完成的過程,就對應着一個棧幀在虛拟機棧中入棧到出棧的過程。

  棧幀( Frame)是用來存儲資料和部分過程結果的資料結構,同時也被用來處理動态連結(Dynamic Linking)、 方法傳回值和異常分派( Dispatch Exception)。

  棧幀随着方法調用而建立,随着方法結束而銷毀——無論方法是正常完成還是異常完成(抛出了在方法内未被捕獲的異常)都算作方法結束。

  

JVM知識點整理(1)-JVM記憶體區域

本地方法區(線程私有):

  本地方法區和Java Stack 作用類似, 差別是虛拟機棧為執行Java 方法服務, 而本地方法棧則為Native 方法服務

堆(Heap-線程共享)-運作時資料區:

  是被線程共享的一塊記憶體區域,建立的對象和數組都儲存在Java 堆記憶體中,也是垃圾收集器進行垃圾收集的最重要的記憶體區域。

  由于現代VM 采用分代收集算法, 是以Java 堆從GC 的角度還可以細分為: 新生代(Eden 區、From Survivor 區和To Survivor 區)和老年代。

方法區/永久代(線程共享):

  即我們常說的永久代(Permanent Generation), 用于存儲被JVM 加載的類資訊、常量、靜态變量、即時編譯器編譯後的代碼等資料.

  HotSpot VM把GC分代收集擴充至方法區, 即使用Java堆的永久代來實作方法區, 這樣HotSpot 的垃圾收集器就可以像管理Java 堆一樣管理這部分記憶體而不必為方法區開發專門的記憶體管理器(永久帶的記憶體回收的主要目标是針對常量池的回收和類型的解除安裝, 是以收益一般很小)。

運作時常量池(Runtime Constant Pool)是方法區的一部分。Class 檔案中除了有類的版本、字段、方法、接口等描述等資訊外, 還有一項資訊是常量池(Constant  Pool Table), 用于存放編譯期生成的各種字面量和符号引用,這部分内容将在類加載後存放到方法區的運作時常量池中。

  Java 虛拟機對Class 檔案的每一部分(自然也包括常量池)的格式都有嚴格的規定, 每一個位元組用于存儲哪種資料都必須符合規範上的要求,這樣才會被虛拟機認可、裝載和執行。