Java 面試:JVM的垃圾回收機(jī)制以及類加載機(jī)制

本人兩年工作經(jīng)驗(yàn),但是在面試過(guò)程中被多次問(wèn)到:java的垃圾回收機(jī)制,但是后面回想起來(lái)似乎回答的都比較模棱兩可,所以在學(xué)習(xí)的過(guò)程中特意記錄如下:

1. JVM 內(nèi)存運(yùn)行時(shí)數(shù)據(jù)的三個(gè)重要地方

? ? · 堆(heap): 他是最大的一個(gè)區(qū)域,用于存放對(duì)象實(shí)例和數(shù)組,是全局共享的

? ? · 棧(stack):全稱為虛擬機(jī)棧,主要存儲(chǔ)基本數(shù)據(jù)類型,以及對(duì)象的引用,私有線程

? ? ·方法區(qū)(Method Area):在class 被加載后的一些信息 如常量,靜態(tài)常量這些被放在這里,在Hotspot里面我們被它 稱之為永生代。

?堆:在JVM中占用的內(nèi)存最多,也叫邏輯堆,主要用來(lái)存放對(duì)象實(shí)例和數(shù)據(jù),對(duì)于所有的線程都是共享的,對(duì)于Heap 堆區(qū)的內(nèi)存是動(dòng)態(tài)分配的,所以空間大小和生命周期都是不明確的,而GC的主要作用就是自動(dòng)釋放邏輯堆的實(shí)例對(duì)象所占的內(nèi)存空間,而在堆的內(nèi)存空間里面又分為新生代和老年代,用來(lái)區(qū)分對(duì)象的存活時(shí)間,在新生代中還被細(xì)分為Eden SurvivorFrom survivorTo 這三部分。

方法區(qū)(Method Area):主要存儲(chǔ)的是類加載器ClassLoad 加載的類信息,存儲(chǔ)包括:類的元數(shù)據(jù),常量池,字段,靜態(tài)變量與方法內(nèi)部的局部變量,以及編譯好的字節(jié)碼。

棧:在每一個(gè)對(duì)的創(chuàng)建,在棧區(qū)都有一個(gè)對(duì)他的引用,記錄了對(duì)象實(shí)例的地址值,對(duì)象實(shí)例信息存儲(chǔ)在堆區(qū)。

pc 寄存器:在多線程中,系統(tǒng)需要給每一個(gè)線程分配一個(gè)線程編號(hào),會(huì)用到寄存器。


如圖:邏輯堆分為年輕代與年老代,而年輕代又分為 Eden Survivor1 Surivoo2 ,對(duì)于一個(gè)新實(shí)例化的對(duì)象都是存儲(chǔ)在Eden區(qū),按照GC的原理,會(huì)回收掉當(dāng)前對(duì)象沒(méi)有被引用的對(duì)象,而一般對(duì)象都是在年輕代就會(huì)死去,所以年輕代需要頻繁的GC清理。

年輕代:

? ? 在年輕代中jvm使用的Mark-copy 算法,顧名思義是有兩個(gè)階段,第一個(gè)階段Mark(標(biāo)記),第二階段 Copy(復(fù)制),Mark主要是標(biāo)記被引用的對(duì)象,清理掉沒(méi)有被引用的實(shí)例,釋放內(nèi)存,然后copy 就是將還被引用的對(duì)象復(fù)制到不同的年齡代。

? ? ?對(duì)于標(biāo)記與區(qū)分年齡代的技術(shù),我們一般都是采用計(jì)數(shù)器,在每一個(gè)對(duì)象都含有引用計(jì)數(shù)器,都是引用指向?qū)ο蟮臅r(shí)候引用計(jì)數(shù)器+1,不在被引用的技術(shù)器減1,對(duì)與垃圾回收策略則是標(biāo)記活的實(shí)例,沒(méi)有被標(biāo)記的實(shí)例全部回收,釋放內(nèi)存。

? ? ?對(duì)于靜態(tài)方法和靜態(tài)變量,我們知道靜態(tài)方法和變量不產(chǎn)生實(shí)例,直接通過(guò)類的引用,使用classLoad 進(jìn)行加載的類數(shù)據(jù)是不存在邏輯堆里面的,而是直接存在與永生待里,也就是方法區(qū)里,這個(gè)類一旦被清除,這個(gè)類里面的所有靜態(tài)方法和靜態(tài)變量就全部被清除了。

老年代:

? ? ? ? 當(dāng)GC觸發(fā)的時(shí)候,Eden區(qū)的對(duì)象會(huì)被轉(zhuǎn)移到Survior1 區(qū),然后再次GC就會(huì)被轉(zhuǎn)換到Survivor2 區(qū),當(dāng)Survivor11區(qū)的對(duì)象太大Survivor2 無(wú)法容納的時(shí)候,就會(huì)直接轉(zhuǎn)到永生代,也就是老年代。

? ? ? 年老代的算法:

? ??Serial GC? ??

? ? ?Parallel GC? ?

? ? ?Parallel Old GC(Parallel Compacting GC)? ??

? ? ?Concurrent Mark & Sweep GC (or “CMS”)

? ? ?Garbage First (G1) GC

關(guān)鍵的兩種:

? ? 1. PS(Parallel Scavenge) : PS執(zhí)行的是Mark-compact 算法的過(guò)程,并且是用多線程進(jìn)程執(zhí)行提高了效率,Mark與年輕代的算法一致,但是Compact 算法則是將老年代的對(duì)象進(jìn)行碎片整理,之后空出多余的內(nèi)存空間。

? ? 2. CMS(Concurrent Mark sweeps):我們簡(jiǎn)稱他為 CMS 算法,對(duì)與cms算法,我們先需要了解一個(gè)概念 Stop the world,對(duì)于Stop the world,不管選擇哪種GC算法,stop-the-world都是不可避免的。Stop-the-world意味著從應(yīng)用中停下來(lái)并進(jìn)入到GC執(zhí)行過(guò)程中去。一旦Stop-the-world發(fā)生,除了GC所需的線程外,其他線程都將停止工作,中斷了的線程直到GC任務(wù)結(jié)束才繼續(xù)它們的任務(wù)。GC調(diào)優(yōu)通常就是為了改善stop-the-world的時(shí)間。在CMS GC開(kāi)始時(shí)的初始標(biāo)記(initial mark)比較簡(jiǎn)單,只有靠近類加載器的存活對(duì)象會(huì)被標(biāo)記,因此停頓時(shí)間(stop-the-world)比較短暫。在并發(fā)標(biāo)記(concurrent mark)階段,由剛被確認(rèn)和標(biāo)記過(guò)的存活對(duì)象所關(guān)聯(lián)的對(duì)象將被會(huì)跟蹤和檢測(cè)存活狀態(tài)。此步驟的不同之處在于有多個(gè)線程并行處理此過(guò)程。在重標(biāo)記(remark)階段,由并發(fā)標(biāo)記所關(guān)聯(lián)的新增或中止的對(duì)象瘵被會(huì)檢測(cè)。在最后的并發(fā)清理(concurrent sweep)階段,垃圾回收過(guò)程被真正執(zhí)行。在垃圾回收?qǐng)?zhí)行過(guò)程中,其他線程依然在執(zhí)行。得益于CMS GC的執(zhí)行方式,在GC期間系統(tǒng)中斷時(shí)間非常短暫。CMS GC也被稱為低延遲GC

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

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

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