jvm知識點總結

1 jvm結構圖

在這裡插入圖片描述

2 類的裝載器

在這裡插入圖片描述
​  將類的位元組碼文件載入到jvm中,會把這些內容轉化為方法區運行的數據結構。jvm會創建對應的Class對象,保存到堆中。

裝載器有如下幾種:虛擬機自帶裝載器:啟動類載入器(BootStrap)C++、擴展類載入器(Extension)Java、應用程式類載入器(AppClassLoader)Java,也叫系統類載入器,載入當前應用的classpath的所有類
用戶自定義載入器:Java.lang.ClassLoader的子類

雙親委派機制:如果一個類收到載入的請求,他首先會讓它的父類嘗試去完成,當他的父類無法完成時,它才會嘗試載入這個類。

沙箱:比如啟動類載入器它載入了java.lang.String,如果本地也是創建相同的包且有String類,它會以啟動的時候首先載入的那個類為準。

3 執行引擎

​ 功能:解釋命令,提交給作業系統執行。

4 本地方法棧、本地方法介面、本地方法庫

​  native修飾的方法是本地方法,由於java程式碼無能為力,可能需要調用作業系統或C++等程式碼。這些方法會註冊到本地方法棧,這些本地方法通過調用本地方法介面調用非java程式碼,執行引擎會載入本地方法庫。

5 PC暫存器

​  用於指向當前執行緒所執行的位元組碼的行號顯示器

6 方法區

​  存儲類的結構資訊,有靜態變數(靜態域),運行時常量池、欄位和方法數據、構造函數和普通方法的位元組碼內容。在jdk7中這裡是永久代,jdk8採用的是元空間實現。

7 棧

​  在執行緒創建時創建,執行緒結束棧記憶體也結束,所有不存在垃圾回收。棧中存儲8種基本數據變數、對象的引用變數、實例方法。棧中存儲的方法就是棧幀,存儲三種數據,本地變數:輸入輸出參數以及方法內的變數,棧的操作:記錄入棧和出棧、棧幀數據:方法。
​  棧中存儲直接對象的地址,堆中存儲對象以及類元數據的地址即Class的地址,方法區存儲類元數據。

8 堆

在這裡插入圖片描述
​  在jdk7中堆在邏輯上分為新生區,養老區,永久存儲區,而在物理上堆只有新生區和養老區,永久存儲區為方法區,在jdk8中永久區被原空間取代,二者區別時永久存儲區使用堆記憶體,而元空間的大小和物理記憶體有關。
​  在伊甸區如果對象滿了,會觸發 Minor GC ,會把存活的對象移動到倖存0區(from),對象的年齡加一。第二次伊甸區對象滿了,會把倖存0區和伊甸區存活的對象複製到倖存1區並且年齡加一,倖存0區有from區變為to區,倖存1區由to變為from區,清理伊甸區和to區,這樣一直進行下去,如果哪些對象年齡達到15,就會進入養老區,這個值也可以自己設置,在jdk8種在0-15之間。如果養老區滿了,會觸發full gc。

9 GC演算法

​  分代收集演算法,新生區和養老區採用的演算法是不一樣的,由於新生區發生gc比較頻繁,而養老區次數比較少,在jdk7中永久存儲區基本不清理,在jdk8中元空間不使用堆記憶體故不需要清理。

9.1 引用計數法

​ 在每次引用時,會加一,置為null會減一,但是這個演算法有如下缺點,要使用計數器,會有記憶體消耗,無法處理循環引用。

9.2 複製演算法

​ 觸發 Minor GC ,會把存活的對象移動到倖存0區(from),對象的年齡加一。第二次伊甸區對象滿了,會把倖存0區和伊甸區存活的對象複製到倖存1區並且年齡加一,倖存0區有from區變為to區,倖存1區由to變為from區,清理伊甸區和to區,這樣一直進行下去,如果哪些對象年齡達到15,就會進入養老區。

缺點:①:消耗記憶體
②:如果生存率高的化,也是比較浪費的。
這個演算法在新生區使用,因為新生區存活率低。

9.3 標記清除

​ ①:從根集合開始掃描,對存活的對象進行標記
​ ②:掃描整個記憶體空間,清理未被標記的對象。

缺點:需要暫停整個應用,會產生記憶體碎片
老年代一般是由標記清除或者是標記清除與標記整理的混合實現

9.4 標記壓縮

​ ①:從根集合開始掃描,對存活的對象進行標記
​ ②:將標記的對象移動到一邊,不需要清理

缺點:雖然不需要回收對象,但是不僅要標記所有存活對象,還要整理所有存活對象的引用地址。

還有一個演算法是標記清除壓縮演算法,這個演算法結合3,4,和標記清除是類似的,只不過多次gc後才進行壓縮。
老年代一般是由標記清除或者是標記清除與標記整理的混合實現

Tags: