JVM梳理

一、類加載機(jī)制

1、什么是類的加載

類的加載指的是將類的.class文件中的二進(jìn)制數(shù)據(jù)讀入到內(nèi)存中,將其放在運(yùn)行時(shí)數(shù)據(jù)區(qū)的方法區(qū)內(nèi),然后在堆區(qū)創(chuàng)建一個(gè)java.lang.Class對象,用來封裝類在方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu)。類的加載的最終產(chǎn)品是位于堆區(qū)中的Class對象,Class對象封裝了類在方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu),并且向Java程序員提供了訪問方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu)的接口

2、類的生命周期

類的生命周期包括:加載、連接、初始化、使用和卸載,其中前三部是類的加載的過程

加載:查找并加載類的二進(jìn)制數(shù)據(jù),在Java堆中也創(chuàng)建一個(gè)java.lang.Class類的對象

連接:連接又包含三塊內(nèi)容:驗(yàn)證、準(zhǔn)備、初始化。1)驗(yàn)證,文件格式、元數(shù)據(jù)、字節(jié)碼、符號引用驗(yàn)證;2)準(zhǔn)備,為類的靜態(tài)變量分配內(nèi)存,并將其初始化為默認(rèn)值;3)解析,把類中的符號引用轉(zhuǎn)換為直接引用

初始化:為類的靜態(tài)變量賦予正確的初始值

使用:new出對象程序中使用

卸載:執(zhí)行垃圾回收

3、類加載器??

啟動類加載器:Bootstrap ClassLoader,負(fù)責(zé)加載存放在JDK\jre\lib(JDK代表JDK的安裝目錄,下同)下,或被-Xbootclasspath參數(shù)指定的路徑中的,并且能被虛擬機(jī)識別的類庫

擴(kuò)展類加載器:Extension ClassLoader,該加載器由sun.misc.Launcher$ExtClassLoader實(shí)現(xiàn),它負(fù)責(zé)加載DK\jre\lib\ext目錄中,或者由java.ext.dirs系統(tǒng)變量指定的路徑中的所有類庫(如javax.*開頭的類),開發(fā)者可以直接使用擴(kuò)展類加載器。

應(yīng)用程序類加載器:Application ClassLoader,該類加載器由sun.misc.Launcher$AppClassLoader來實(shí)現(xiàn),它負(fù)責(zé)加載用戶類路徑(ClassPath)所指定的類,開發(fā)者可以直接使用該類加載器

4、類加載機(jī)制

全盤負(fù)責(zé),當(dāng)一個(gè)類加載器負(fù)責(zé)加載某個(gè)Class時(shí),該Class所依賴的和引用的其他Class也將由該類加載器負(fù)責(zé)載入,除非顯示使用另外一個(gè)類加載器來載入

父類委托,先讓父類加載器試圖加載該類,只有在父類加載器無法加載該類時(shí)才嘗試從自己的類路徑中加載該類

緩存機(jī)制,緩存機(jī)制將會保證所有加載過的Class都會被緩存,當(dāng)程序中需要使用某個(gè)Class時(shí),類加載器先從緩存區(qū)尋找該Class,只有緩存區(qū)不存在,系統(tǒng)才會讀取該類對應(yīng)的二進(jìn)制數(shù)據(jù),并將其轉(zhuǎn)換成Class對象,存入緩存區(qū)。這就是為什么修改了Class后,必須重啟JVM,程序的修改才會生效

二、JVM內(nèi)存結(jié)構(gòu)

1、內(nèi)存結(jié)構(gòu)

Java堆(Heap),是Java虛擬機(jī)所管理的內(nèi)存中最大的一塊。Java堆是被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動時(shí)創(chuàng)建。此內(nèi)存區(qū)域的唯一目的就是存放對象實(shí)例,幾乎所有的對象實(shí)例都在這里分配內(nèi)存。

方法區(qū)(Method Area),方法區(qū)(Method Area)與Java堆一樣,是各個(gè)線程共享的內(nèi)存區(qū)域,它用于存儲已被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。

程序計(jì)數(shù)器(Program Counter Register),程序計(jì)數(shù)器(Program Counter Register)是一塊較小的內(nèi)存空間,它的作用可以看做是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器。

JVM棧(JVM Stacks),與程序計(jì)數(shù)器一樣,Java虛擬機(jī)棧(Java Virtual Machine Stacks)也是線程私有的,它的生命周期與線程相同。虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型:每個(gè)方法被執(zhí)行的時(shí)候都會同時(shí)創(chuàng)建一個(gè)棧幀(Stack Frame)用于存儲局部變量表、操作棧、動態(tài)鏈接、方法出口等信息。每一個(gè)方法被調(diào)用直至執(zhí)行完成的過程,就對應(yīng)著一個(gè)棧幀在虛擬機(jī)棧中從入棧到出棧的過程。

本地方法棧(Native Method Stacks),本地方法棧(Native Method Stacks)與虛擬機(jī)棧所發(fā)揮的作用是非常相似的,其區(qū)別不過是虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法(也就是字節(jié)碼)服務(wù),而本地方法棧則是為虛擬機(jī)使用到的Native方法服務(wù)。

2、堆區(qū)結(jié)構(gòu)

Java堆區(qū)分為Young(新生代)和Old(老年代)兩塊大的區(qū)域,其中Young和Old區(qū)域默認(rèn)比例為1:2( 該值可以通過參數(shù) –XX:NewRatio 來指定 )。Young區(qū)內(nèi)又分為Eden、Survivor from和Survivor to三個(gè)區(qū)域,比例為8:1:1.JVM 每次只會使用 Eden 和其中的一塊 Survivor 區(qū)域來為對象服務(wù),所以無論什么時(shí)候,總是有一塊 Survivor 區(qū)域是空閑著的。因此,新生代實(shí)際可用的內(nèi)存空間為 9/10 ( 即90% )的新生代空間。

2、對象分配規(guī)則

對象優(yōu)先分配在Eden區(qū),如果Eden區(qū)沒有足夠的空間時(shí),虛擬機(jī)執(zhí)行一次Minor?GC。

大對象直接進(jìn)入老年代(大對象是指需要大量連續(xù)內(nèi)存空間的對象)。這樣做的目的是避免在Eden區(qū)和兩個(gè)Survivor區(qū)之間發(fā)生大量的內(nèi)存拷貝(新生代采用復(fù)制算法收集內(nèi)存)。

長期存活的對象進(jìn)入老年代。虛擬機(jī)為每個(gè)對象定義了一個(gè)年齡計(jì)數(shù)器,如果對象經(jīng)過了1次Minor?GC那么對象會進(jìn)入Survivor區(qū),之后每經(jīng)過一次Minor?GC那么對象的年齡加1,知道達(dá)到閥值對象進(jìn)入老年區(qū)。

動態(tài)判斷對象的年齡。如果Survivor區(qū)中相同年齡的所有對象大小的總和大于Survivor空間的一半,年齡大于或等于該年齡的對象可以直接進(jìn)入老年代。

空間分配擔(dān)保。每次進(jìn)行Minor?GC時(shí),JVM會計(jì)算Survivor區(qū)移至老年區(qū)的對象的平均大小,如果這個(gè)值大于老年區(qū)的剩余值大小則進(jìn)行一次Full?GC,如果小于檢查HandlePromotionFailure設(shè)置,如果true則只進(jìn)行Monitor?GC,如果false則進(jìn)行Full?GC。

三、GC算法和垃圾回收器

1、對象存活判斷

引用計(jì)數(shù):每個(gè)對象有一個(gè)引用計(jì)數(shù)屬性,新增一個(gè)引用時(shí)計(jì)數(shù)加1,引用釋放時(shí)計(jì)數(shù)減1,計(jì)數(shù)為0時(shí)可以回收。此方法簡單,無法解決對象相互循環(huán)引用的問題。

可達(dá)性分析(Reachability Analysis):從GC Roots開始向下搜索,搜索所走過的路徑稱為引用鏈。當(dāng)一個(gè)對象到GC Roots沒有任何引用鏈相連時(shí),則證明此對象是不可用的,不可達(dá)對象。

2、GC算法

標(biāo)記 -清除算法,“標(biāo)記-清除”(Mark-Sweep)算法,如它的名字一樣,算法分為“標(biāo)記”和“清除”兩個(gè)階段:首先標(biāo)記出所有需要回收的對象,在標(biāo)記完成后統(tǒng)一回收掉所有被標(biāo)記的對象。

復(fù)制算法,“復(fù)制”(Copying)的收集算法,它將可用內(nèi)存按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當(dāng)這一塊的內(nèi)存用完了,就將還存活著的對象復(fù)制到另外一塊上面,然后再把已使用過的內(nèi)存空間一次清理掉。

標(biāo)記-壓縮算法,標(biāo)記過程仍然與“標(biāo)記-清除”算法一樣,但后續(xù)步驟不是直接對可回收對象進(jìn)行清理,而是讓所有存活的對象都向一端移動,然后直接清理掉端邊界以外的內(nèi)存

分代收集算法,“分代收集”(Generational Collection)算法,把Java堆分為新生代和老年代,這樣就可以根據(jù)各個(gè)年代的特點(diǎn)采用最適當(dāng)?shù)氖占惴ā?/p>

3、垃圾回收器

Serial收集器,串行收集器是最古老,最穩(wěn)定以及效率高的收集器,可能會產(chǎn)生較長的停頓,只使用一個(gè)線程去回收。

ParNew收集器,ParNew收集器其實(shí)就是Serial收集器的多線程版本。

Parallel收集器,Parallel Scavenge收集器類似ParNew收集器,Parallel收集器更關(guān)注系統(tǒng)的吞吐量。

Parallel Old 收集器,Parallel Old是Parallel Scavenge收集器的老年代版本,使用多線程和“標(biāo)記-整理”算法

CMS收集器,CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時(shí)間為目標(biāo)的收集器。

G1收集器,G1 (Garbage-First)是一款面向服務(wù)器的垃圾收集器,主要針對配備多顆處理器及大容量內(nèi)存的機(jī)器. 以極高概率滿足GC停頓時(shí)間要求的同時(shí),還具備高吞吐量性能特征

4、垃圾回收器分析

垃圾回收器從線程運(yùn)行情況分類有三種

(1)串行回收,Serial回收器,單線程回收,全程stw

(2)并行回收,名稱以Parallel開頭的回收器,多線程回收,全程stw

(3)并發(fā)回收,cms與G1,多線程分階段回收,只有某階段會stw;

CMS垃圾回收器的特點(diǎn)

(1)cms只會回收老年代和永久帶(1.8開始為元數(shù)據(jù)區(qū),需要設(shè)置CMSClassUnloadingEnabled),不會收集年輕帶;

(2)cms是一種預(yù)處理垃圾回收器,它不能等到old內(nèi)存用盡時(shí)回收,需要在內(nèi)存用盡前,完成回收操作,否則會導(dǎo)致并發(fā)回收失敗;所以cms垃圾回收器開始執(zhí)行回收操作,有一個(gè)觸發(fā)閾值,默認(rèn)是老年代或永久帶達(dá)到92%;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 《深入理解Java虛擬機(jī)》筆記_第一遍 先取看完這本書(JVM)后必須掌握的部分。 第一部分 走近 Java 從傳...
    xiaogmail閱讀 5,473評論 1 34
  • 內(nèi)存溢出和內(nèi)存泄漏的區(qū)別 內(nèi)存溢出:out of memory,是指程序在申請內(nèi)存時(shí),沒有足夠的內(nèi)存空間供其使用,...
    Aimerwhy閱讀 806評論 0 1
  • 介紹JVM中7個(gè)區(qū)域,然后把每個(gè)區(qū)域可能造成內(nèi)存的溢出的情況說明 程序計(jì)數(shù)器:看做當(dāng)前線程所執(zhí)行的字節(jié)碼行號指示器...
    jemmm閱讀 2,306評論 0 9
  • 工作之余,想總結(jié)一下JVM相關(guān)知識。 Java運(yùn)行時(shí)數(shù)據(jù)區(qū): Java虛擬機(jī)在執(zhí)行Java程序的過程中會將其管理的...
    Huang遠(yuǎn)閱讀 683評論 0 2
  • 第二部分 自動內(nèi)存管理機(jī)制 第二章 java內(nèi)存異常與內(nèi)存溢出異常 運(yùn)行數(shù)據(jù)區(qū)域 程序計(jì)數(shù)器:當(dāng)前線程所執(zhí)行的字節(jié)...
    小明oh閱讀 1,284評論 0 2

友情鏈接更多精彩內(nèi)容