成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JAVA GC 原理詳解

wangjuntytl / 1127人閱讀

摘要:虛擬機(jī)棧區(qū)也就是通常所說的棧區(qū),它描述的是方法執(zhí)行的內(nèi)存模型,每個(gè)方法被執(zhí)行的時(shí)候都創(chuàng)建一個(gè)棧幀,用于存儲(chǔ)局部變量表操作數(shù)棧動(dòng)態(tài)鏈接方法出口等。每個(gè)方法被調(diào)用到完成,相當(dāng)于一個(gè)棧幀在虛擬機(jī)棧中從入棧到出棧的過程。

大多數(shù)情況下我們對(duì)GC的了解都只是淺層含義上的,下面我們來詳細(xì)講解下內(nèi)部的一些實(shí)現(xiàn)原理。
講解GC之前,我們得先了解下JVM的內(nèi)存結(jié)構(gòu),才能讓我們理解GC導(dǎo)致是干嘛的。

一.JVM 內(nèi)存結(jié)構(gòu)

JVM內(nèi)存結(jié)構(gòu)由5個(gè)部分組成,分別如下

1. 程序計(jì)數(shù)器(Program Conuter Register)

一塊較小的內(nèi)存空間,它是當(dāng)前線程執(zhí)行字節(jié)碼的行號(hào)指示器,字節(jié)碼解釋工作器就是通過改變這個(gè)計(jì)數(shù)器的值來選取下一條需要執(zhí)行的指令。它是線程私有的內(nèi)存,也是唯一一個(gè)沒有OOM異常的區(qū)域。

2. Java虛擬機(jī)棧區(qū)(Java Virtual Machine Stacks)

也就是通常所說的棧區(qū),它描述的是Java方法執(zhí)行的內(nèi)存模型,每個(gè)方法被執(zhí)行的時(shí)候都創(chuàng)建一個(gè)棧幀(Stack Frame),用于存儲(chǔ)局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口等。每個(gè)方法被調(diào)用到完成,相當(dāng)于一個(gè)棧幀在虛擬機(jī)棧中從入棧到出棧的過程。此區(qū)域也是線程私有的內(nèi)存,可能拋出兩種異常:如果線程請(qǐng)求的棧深度大于虛擬機(jī)允許的深度將拋出StackOverflowError;如果虛擬機(jī)??梢詣?dòng)態(tài)的擴(kuò)展,擴(kuò)展到無法動(dòng)態(tài)的申請(qǐng)到足夠的內(nèi)存時(shí)會(huì)拋出OOM異常。

3. 本地方法棧(Native Method Stacks)

本地方法棧與虛擬機(jī)棧發(fā)揮的作用非常相似,區(qū)別就是虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法,本地方法棧則是為虛擬機(jī)使用到的Native方法服務(wù)。

4. 堆區(qū)(Heap)

所有對(duì)象實(shí)例和數(shù)組都在堆區(qū)上分配,堆區(qū)是GC主要管理的區(qū)域。堆區(qū)還可以細(xì)分為新生代、老年代,新生代還分為一個(gè)Eden區(qū)和兩個(gè)Survivor區(qū)。此塊內(nèi)存為所有線程共享區(qū)域,當(dāng)堆中沒有足夠內(nèi)存完成實(shí)例分配時(shí)會(huì)拋出OOM異常。

5. 方法區(qū)(Method Area)

方法區(qū)也是所有線程共享區(qū),用于存儲(chǔ)已被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時(shí)編譯后的代碼等數(shù)據(jù)。GC在這個(gè)區(qū)域很少出現(xiàn),這個(gè)區(qū)域內(nèi)存回收的目標(biāo)主要是對(duì)常量池的回收和類型的卸載,回收的內(nèi)存比較少,所以也有稱這個(gè)區(qū)域?yàn)橛谰么?Permanent Generation)的。當(dāng)方法區(qū)無法滿足內(nèi)存分配時(shí)拋出OOM異常。

二.GC 原理

針對(duì)GC的原理機(jī)制,主要搞清楚下面三個(gè)問題。

什么時(shí)候回收?

哪些需要回收?

怎么回收?

1. 什么時(shí)候回收?

1.對(duì)象優(yōu)先分配到新生代的Eden區(qū),當(dāng)不夠空間的時(shí)候進(jìn)行一次Minor GC,清理頻率很高。
2.Full GC發(fā)生在老年代,當(dāng)不夠空間的時(shí)候進(jìn)行一次Full GC,伴隨著也會(huì)進(jìn)行一次Minor GC。
3.進(jìn)行Minor GC時(shí),會(huì)判斷每次變成晉升到老年代的對(duì)象平均值是否大于老年代剩余空間,如果大于,則進(jìn)行一次Full GC,如果小于就會(huì)去判斷HandlePromotionFailure設(shè)置是否允許擔(dān)保失敗,如果允許,則進(jìn)行Minor GC,不允許則改為Full GC。

上面提到GC主要管理的是堆區(qū),堆區(qū)主要分為`新生代`和`老年代`
* 【新生代】分為一個(gè)Eden和兩個(gè)Survivor區(qū)。新new的對(duì)象都放在這里,很快消亡。
* 【老年代】新new的大對(duì)象直接丟到這里(為了避免在Eden區(qū)和兩個(gè)Survivor區(qū)發(fā)生大量的內(nèi)存拷貝),其余就是在新生代多次回收沒被干掉過來變成老家伙的對(duì)象了。
2. 哪些需要回收?

當(dāng)調(diào)用了finalize()方法后,則需要進(jìn)行清理,具體場(chǎng)景如上。

* 什么是finalize()方法?

每次進(jìn)行GC之前系統(tǒng)都會(huì)調(diào)用一次finalize()方法,用以清理所有活動(dòng)并且釋放資源。

* 什么時(shí)候調(diào)用finalize()方法?

1.GC調(diào)用之前,例如運(yùn)行System.gc();(調(diào)用System.gc()只是建議JVM去執(zhí)行,是否執(zhí)行還得JVM去判斷)
2.程序退出時(shí),每個(gè)對(duì)象都會(huì)調(diào)用finalzie
3.顯式調(diào)用finalize
3. 怎么回收?

JVM會(huì)根據(jù)不同的收集器使用不同的算法組合來達(dá)到回收的效果

### 垃圾收集算法

* mark-sweep(標(biāo)記-清除)- 標(biāo)記所有需要回收的對(duì)象,在標(biāo)記完成后統(tǒng)一回收這些對(duì)象。

缺點(diǎn):1.標(biāo)記和清除兩個(gè)過程的效率都不高。2.標(biāo)記清除會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片。

* copying(復(fù)制)- 主要用來回收新生代

新生代分為一個(gè)Eden區(qū)、兩個(gè)Survivor區(qū)(Survivor0、Survivor1),Eden和Survivor默認(rèn)8:1?;厥諘r(shí)先把Eden存活對(duì)象復(fù)制到Survivor0區(qū),清空Eden區(qū),當(dāng)Survivor0區(qū)滿了以后,把Eden和Survivor0區(qū)的存活對(duì)象復(fù)制到Survivor1區(qū),清空Eden區(qū)和Survivor0區(qū),之后交換Survivor0和Survivor1區(qū),保持Survivor1區(qū)是空的,如此往復(fù)

* mark-compact(標(biāo)記-整理)

主要用來回收老年代。標(biāo)記需要回收的對(duì)象,將其他存活的對(duì)象都向一端移動(dòng),然后直接清理掉端邊界以外的內(nèi)存。

* generational collection(分代)

目前常用的收集算法,區(qū)分新生代和老年代做不同的算法收集。針對(duì)新生代,只有少量存活,選用復(fù)制算法。針對(duì)老年代,存活率高,沒有額外的空間對(duì)它進(jìn)行分配擔(dān)保,就必須使用“標(biāo)記-清理”或者“標(biāo)記-整理”算法來進(jìn)行回收。

--------

### 垃圾收集器

* Serial 、Serial Old 收集器 [-XX:+UseSerialGC,使用 Serial + Serial Old 組合回收]

適合單處理器系統(tǒng),并且在進(jìn)行垃圾回收的時(shí)候會(huì)暫停其他所有的工作線程(stop the world),對(duì)于多處理器的系統(tǒng)來說是災(zāi)難

* ParNew 收集器 [-XX:UseParallelGC,使用 Parallel Scavenge + Serial Old 組合回收]

serial 收集器的多線程版本。ParNew是許多運(yùn)行在Server模式下的虛擬機(jī)中首選的新生代收集器,除了Serial收集器外,只有它能與CMS收集器配合工作

* Parallel Scavenge 、Parallel Old 收集器 [-XX:GCTimeRatio,-XX:MaxGCPauseMillis]

通過兩個(gè)參數(shù)GCTimeRatio和MaxGCPauseMillis,盡可能縮短垃圾收集器用戶線程的停頓時(shí)間,從而達(dá)到一個(gè)可控制的吞吐量。

* CMS (Concurrent Mark Sweep)收集器 [-XX:UseConcMarkSweepGC,使用 ParNew + CMS + Serial Old 組合回收]

以獲取最短回收停頓時(shí)間為目標(biāo)的收集器。

步驟

1.初始標(biāo)記(CMS initial mark),標(biāo)記GC Roots能直接關(guān)聯(lián)到的對(duì)象,速度很快
2.并發(fā)標(biāo)記(CMS concurrent mark),進(jìn)行GC Roots Tracing
3.重新標(biāo)記(CMS remark),重新標(biāo)記階段是為了修正并發(fā)標(biāo)記期間因用戶程序繼續(xù)運(yùn)作而導(dǎo)致變動(dòng)的標(biāo)記記錄,比并發(fā)標(biāo)記時(shí)間短
4.并發(fā)清除(CMS concurrent sweep)并行刪除

缺點(diǎn)
1. 比較消耗CPU資源,默認(rèn)啟動(dòng)回收線程數(shù)是(CPU數(shù)量+3)/4。
2. CMS收集器無法處理浮動(dòng)垃圾(CMS清理階段用戶線程還運(yùn)行著,伴隨生成的新垃圾只能在下次GC再清理掉),可能出現(xiàn)“Concurrent Mode Failure”而導(dǎo)致另一次Full GC的產(chǎn)生??梢酝ㄟ^-XX:CMSInitiatingOccupancyFraction來調(diào)節(jié)。
3. 標(biāo)記-清除會(huì)導(dǎo)致內(nèi)存碎片而導(dǎo)致觸發(fā)Full GC(切換到Serial Old收集器收集老年代)??梢酝ㄟ^-XX:UseCMSCompactAtFullCollection、-XX:CMSFullGCsBeforeCompaction來調(diào)節(jié)。

* G1(Garbage-First) 收集器 [-XX:+UseG1GC]

Java堆的內(nèi)存分布和其他收集器有很大不同,它將整個(gè)Java堆劃分為多個(gè)大小相等的獨(dú)立區(qū)域`Region`,老年代和新生代不再物理隔離,而是一部分`Region`的集合。G1設(shè)計(jì)初衷是為了縮短大堆(>4GB)時(shí)的停頓時(shí)間。它會(huì)跟蹤各個(gè)Region的垃圾堆積價(jià)值大小,后臺(tái)維護(hù)一個(gè)優(yōu)先列表,每次根據(jù)允許的收集時(shí)間,優(yōu)先回收價(jià)值最大的`Region`。

特點(diǎn)
1.并發(fā)和并行
2.分代收集
3.空間整合
4.可預(yù)測(cè)的停頓

步驟
1.初始標(biāo)記(Initial Marking)
2.并發(fā)標(biāo)記(Concurrent Marking)
3.最終標(biāo)記(Final Marking)
4.篩選回收(Live Data Counting and Evacuation)

補(bǔ)充:

1、并行Parallel-XX:+UseParalleGC,追求吞吐量
多條垃圾收集線程并行工作,但此時(shí)用戶線程仍然處于等待狀態(tài)
2、并發(fā)ConcurrentUseConcMarkSweepGC,追求響應(yīng)速度
指用戶線程與垃圾收集線程同時(shí)執(zhí)行(但并不一定是并行的,可能會(huì)交替執(zhí)行),用戶程序在繼續(xù)運(yùn)行,而垃圾收集程序運(yùn)行于另一個(gè)CPU上

串行處理器: Serial
--適用情況:數(shù)據(jù)量比較?。?00M左右);單處理器下并且對(duì)響應(yīng)時(shí)間無要求的應(yīng)用。
--缺點(diǎn):只能用于小型應(yīng)用
并行處理器:UseParalleGC
--適用情況:“對(duì)吞吐量有高要求”,多CPU、對(duì)應(yīng)用響應(yīng)時(shí)間無要求的中、大型應(yīng)用。舉例:后臺(tái)處理、科學(xué)計(jì)算。
--缺點(diǎn):應(yīng)用響應(yīng)時(shí)間可能較長(zhǎng)
并發(fā)處理器:UseConcMarkSweepGC
--適用情況:“對(duì)響應(yīng)時(shí)間有高要求”,多CPU、對(duì)應(yīng)用響應(yīng)時(shí)間有較高要求的中、大型應(yīng)用。舉例:Web服務(wù)器/應(yīng)用服務(wù)器、電信交換、集成開發(fā)環(huán)境。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/69869.html

相關(guān)文章

  • 后臺(tái)開發(fā)常問面試題集錦(問題搬運(yùn)工,附鏈接)

    摘要:基礎(chǔ)問題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關(guān)鍵字修飾符知識(shí)點(diǎn)總結(jié)必看篇中的關(guān)鍵字解析回調(diào)機(jī)制解讀抽象類與三大特征時(shí)間和時(shí)間戳的相互轉(zhuǎn)換為什么要使用內(nèi)部類對(duì)象鎖和類鎖的區(qū)別,,優(yōu)缺點(diǎn)及比較提高篇八詳解內(nèi)部類單例模式和 Java基礎(chǔ)問題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...

    spacewander 評(píng)論0 收藏0
  • 后臺(tái)開發(fā)常問面試題集錦(問題搬運(yùn)工,附鏈接)

    摘要:基礎(chǔ)問題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關(guān)鍵字修飾符知識(shí)點(diǎn)總結(jié)必看篇中的關(guān)鍵字解析回調(diào)機(jī)制解讀抽象類與三大特征時(shí)間和時(shí)間戳的相互轉(zhuǎn)換為什么要使用內(nèi)部類對(duì)象鎖和類鎖的區(qū)別,,優(yōu)缺點(diǎn)及比較提高篇八詳解內(nèi)部類單例模式和 Java基礎(chǔ)問題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...

    xfee 評(píng)論0 收藏0
  • 后臺(tái)開發(fā)常問面試題集錦(問題搬運(yùn)工,附鏈接)

    摘要:基礎(chǔ)問題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關(guān)鍵字修飾符知識(shí)點(diǎn)總結(jié)必看篇中的關(guān)鍵字解析回調(diào)機(jī)制解讀抽象類與三大特征時(shí)間和時(shí)間戳的相互轉(zhuǎn)換為什么要使用內(nèi)部類對(duì)象鎖和類鎖的區(qū)別,,優(yōu)缺點(diǎn)及比較提高篇八詳解內(nèi)部類單例模式和 Java基礎(chǔ)問題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...

    makeFoxPlay 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<