JVM GC原理深度解析及性能調優實戰(一)

JVM基本概念

jvm是可以運行java代碼的虛擬計算機,包括一套字節碼指令集、一組寄存器、一個棧、一個垃圾回收、堆和一個方法存儲區。JVM運行在操作系統之上,和物理硬件沒有直接的交互。

先來看一張知識拓撲圖

JVM GC原理深度解析及性能調優實戰(一)

jvm知識拓撲

運行過程:.java文件通過編譯器(IDEA)生成相應的.class文件,也就是字節碼文件,而字節碼文件又通過jvm 的解釋器,編譯成特定機器上的機器碼。

每一種平臺的解釋器是不同的,但是實現的虛擬機是相同的,這也就是java 為什麼能夠跨平臺的原因,當一個程序開始運行,這個時候虛擬機就開始實例化了,多個程序啟動就會有多個虛擬機的實例,程序退出或關閉,虛擬機實例消亡,多個虛擬機之間數據不共享。


JVM內存區域

講述JVM內存之前先了解先jvm 中的線程

jvm允許一個應用併發執行多個線程,jvm中的線程與原生操作系統的線程有直接映射關係,當jvm中的線程本地存儲、緩衝區分配、同步對象、棧、程序計數器等準備就緒後,就會創建原生系統的線程,操作系統負責調度所有線程,並把他們分配到任何可用的CPU上。當原生線程初始化完畢,就會執行java 代碼中的run方法,當執行完成時,會釋放jvm及原生系統線程所佔用的資源。

JVM GC原理深度解析及性能調優實戰(一)

JVM 內存區域主要分為線程私有區域【程序計數器、虛擬機棧、本地方法區】、線程共享區

域【 JAVA 堆、方法區】、直接內存。

JVM GC原理深度解析及性能調優實戰(一)

線程私有數據區域生命週期與線程相同, 依賴用戶線程的啟動/結束 而 創建/銷燬(在Hotspot VM內, 每個線程都與操作系統的本地線程直接映射, 因此這部分內存區域的存/否跟隨本地線程的生/死對應)。

線程共享區域隨虛擬機的啟動/關閉而創建/銷燬。

直接內存並不是JVM運行時數據區的一部分, 但也會被頻繁的使用: 在JDK 1.4引入的NIO提供了基於Channel與Buffer的IO方式, 它可以使用Native函數庫直接分配堆外內存, 然後使用DirectByteBuffer對象作為這塊內存的引用進行操作(詳見: Java I/O 擴展), 這樣就避免了在Java堆和Native堆中來回複製數據, 因此在一些場景中可以顯著提高性能。

程序計數器:一塊較小的內存空間, 是當前線程所執行的字節碼的行號指示器,每條線程都要有一個獨立的程序計數器,這類內存也稱為“線程私有”的內存。

正在執行java方法的話,計數器記錄的是虛擬機字節碼指令的地址(當前指令的地址)。如果還是Native方法,則為空。

這個內存區域是唯一一個在虛擬機中沒有規定任何OutOfMemoryError情況的區域。

虛擬機棧:是描述java方法執行的內存模型,

每個方法在執行的同時都會創建一個棧幀(Stack Frame)用於存儲局部變量表、操作數棧、動態鏈接、方法出口等信息。每一個方法從調用直至執行完成的過程,就對應著一個棧幀在虛擬機棧中入棧到出棧的過程。

棧幀( Frame)是用來存儲數據和部分過程結果的數據結構,同時也被用來處理動態鏈接 (Dynamic Linking)、 方法返回值和異常分派( Dispatch Exception)。棧幀隨著方法調用而創建,隨著方法結束而銷燬——無論方法是正常完成還是異常完成(拋出了在方法內未被捕獲的異常)都算作方法結束。

本地方法區:本地方法區和Java Stack作用類似, 區別是虛擬機棧為執行Java方法服務, 而本地方法棧則為Native方法服務, 如果一個VM實現使用C-linkage模型來支持Native調用, 那麼該棧將會是一個C棧,但HotSpot VM直接就把本地方法棧和虛擬機棧合二為一

堆:是被線程共享的一塊內存區域,創建的對象和數組都保存在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文件的每一部分(自然也包括常量池)的格式都有嚴格的規定,每一個字節用於存儲哪種數據都必須符合規範上的要求,這樣才會被虛擬機認可、裝載和執行。

附上拓撲圖梳理下

JVM GC原理深度解析及性能調優實戰(一)

下一篇:jvm運行時內存及垃圾回收器


分享到:


相關文章: