最近在學習jvm,看了不少相關知識,俗話說好記性不如爛筆頭,因而在這總結一下。java
jvm整體梳理:程序員
jvm體系整體分爲四個模塊:算法
一、類的加載機制緩存
二、jvm內存結構數據結構
三、GC算法 垃圾回收jvm
四、GC分析 命令調優學習
下面分別大致歸納一下。spa
類的加載機制線程
什麼是類的加載
對象
類的生命週期
類加載器
雙親委派模型
什麼是類的加載
類的加載指的是將類的class文件中二進制數據讀入到內存中,將其放在運行時數據區的方法區內,而後在堆區建立一個java.lang.Class對象,用來封裝類在方法區內的數據結構。類的加載的最終產品是位於堆區中的Class對象,Class對象封裝了類在方法區內的數據結構,而且向java程序員提供了訪問方法區內的數據結構的接口。
類的生命週期
類的生命週期包括這幾個部分。加載、鏈接、初始化、使用和卸載,其中前三部是類的加載的過程,以下圖:
加載,查找並加載類的二進制數據,在java堆中也建立一個java.lang.Class對象
鏈接,鏈接又包含三個內容:驗證、準備、初始化。1)驗證,文件格式、元數據、字節碼、符號引用驗證;
2)、準備,爲類的靜態變量分配內存,並將其初始化爲默認值;3)、解析 把類中的符號引用轉換爲直接引用
初始化,爲類的靜態變量賦予正確的初始值
使用,new出對象 程序中使用
卸載,執行垃圾回收機制
類加載器
啓動類加載器:Bootstrap ClassLoader,負責加載存放在JDK\jre\lib(JDK表明JDK的安裝目錄,下同)下,或被-Xbootclasspath參數指定的路徑中的,而且能被虛擬機識別的類庫
擴展類加載器:Extension ClassLoader,該加載器由sun.misc.Launcher$ExtClassLoader實現,它負責加載DK\jre\lib\ext目錄中,或者由java.ext.dirs系統變量指定的路徑中的全部類庫(如javax.*開頭的類),開發者能夠直接使用擴展類加載器。
應用程序類加載器:Application ClassLoader,該類加載器由sun.misc.Launcher$AppClassLoader來實現,它負責加載用戶類路徑(ClassPath)所指定的類,開發者能夠直接使用該類加載器
類加載機制
全盤負責,當一個類加載器負責加載某個Class時,該Class所依賴的和引用的其餘的Class也將由該類加載器負責載入,除非顯示使用另外一個類加載器來載入。
父類委託,先讓父類加載器視試圖加載該類,只有在父類加載器沒法加載該類時才嘗試從本身的類路徑中加載該類。
緩存機制,緩存機制將會保證全部加載過的class都會被緩存,當程序中須要使用某個class時,類加載器會先從緩存中尋找該class,只有緩存不存在,系統纔會讀取該類對應的二進制數據,並將其轉化爲class對象,存入緩存區。這就是爲何修改了class後,必須重啓jvm,程序的修改纔會生效。
jvm內存結構
主要關注:
jvm內存結構都是什麼
對象分配規則
jvm內存結構
方法區和堆是全部線程共享的內存區域,而java棧、本地方法棧、程序計數器都是運行時線程本身私有的內存區域。
java堆(heap) 是java虛擬機管理的內存最大的一塊區域。java堆是被全部線程共享的一塊內存區域,在虛擬機啓動時建立。此內存區域的惟一目的是存放對象實例,幾乎全部的對象實例都在這裏分配內存。
方法區 方法區和java堆同樣,是全部線程共享的一塊內存區域,它用來存儲已被虛擬機加載的類信息、常量、靜態常量、即便編譯器編譯後的代碼等數據。
程序計數器,程序計數器是一塊較小的內存空間,它的做用能夠看作當前線程所執行的字節碼的行號指示器。
jvm棧,與程序計數器同樣,java虛擬機棧也是線程私有的,他的生命週期與線程相同,虛擬機棧是描述的java方法執行的內存模型,每一個方法被執行時都會同時建立一個棧幀用來存儲局部變量表、操做棧、動態連接、方法出口等信息。每個方法沒調用直至執行完成的過程,就對應着一個棧幀在虛擬機棧中從入棧到出棧的過程。
本地方法棧,本地方法棧與虛擬機棧所發揮的做用是很是類似的,其區別不過是 虛擬機棧是爲虛擬機執行java方法(也就是字節碼)服務,而本地方法棧則是爲虛擬機使用的native方法服務。
對象分配規則
對象優先分在Eden區,若是Eden區沒有足夠的空間,則虛擬機執行一次Minor Gc.
大對象直接進入老年代(大對象是指須要大量連續內存空間的對象)。這樣作的目的是避免在Eden區和兩個Survivor區之間發生大量的內存拷貝(新生代採用複製算法收集內存)。
長期存活的對象進入老年代。虛擬機爲每一個對象定義了一個年齡計數器,若是對象通過一次Minor Gc那麼對象會進入Survivor區,以後沒通過一次MInor Gc那麼對象年齡加1,直到達到閥值對象進入老年區。
動態判斷對象的年齡。若是Survivor區中相同年齡的對象大於Survivor空間的一半,年齡大於該年齡的對象能夠直接進入老年區。
空間分配擔保。每次進行Minor Gc時,jvm都會計算Survivor區移至老年區的對象的平均大小,若是這個值大於年老區的剩餘值大小,則進行一次Full Gc