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: