JVM垃圾收集器及內(nèi)存模型-基礎(chǔ)

總覽

Serial

Serial是最基本、發(fā)展歷史最悠久的收集器。在JDK 1.3.1之前是JAVA虛擬機(jī)新生代收集的唯一選擇
新生代Serial,采用復(fù)制算法。
老年代Serial Old,采用標(biāo)記整理算法
參數(shù)
-XX:+UseSerialGC,新生代、老年代都會(huì)使用串行回收器。
特點(diǎn)

  1. 在進(jìn)行垃圾收集時(shí),必須暫停其他所有工作線程;
  2. 單線程。“單線程”并不僅僅說(shuō)明它只會(huì)使用一個(gè)CPU或一個(gè)收集線程去完成垃圾收集工作;
  3. 簡(jiǎn)單而高效(與其他收集器的單線程比),對(duì)于限定單個(gè)CPU的環(huán)境來(lái)說(shuō),沒(méi)有線程交互的開(kāi)銷,專心做GC,自然可以獲得最高的單線程效率。
  4. Serial收集器對(duì)于運(yùn)行在client模式下的應(yīng)用是一個(gè)很好的選擇(到目前為止,它依然是虛擬機(jī)運(yùn)行在client模式下的默認(rèn)新生代收集器)

ParNew

ParNew收集器其實(shí)就是Serial收集器的多線程版本。
新生代ParNew,采用復(fù)制算法
老年代:不可用
參數(shù)
-XX:+UseParNewGC 新生代開(kāi)啟ParNew收集器+老年代串行
-XX:ParallelGCThreads 設(shè)置并行收集線程數(shù)量
特點(diǎn)

  1. 在進(jìn)行垃圾收集時(shí),必須暫停其他所有工作線程;
  2. 并行多線程,其余的行為、特點(diǎn)和Serial收集器一樣,兩個(gè)收集器共用了許多代碼;
  3. 指定使用CMS后,會(huì)默認(rèn)使用ParNew作為新生代收集(-XX:+UseConcMarkSweepGC);
  4. Server模式下,ParNew收集器是一個(gè)非常重要的收集器,因?yàn)槌齋erial外,目前只有它能與CMS收集器配合工作;
  5. 多條GC線程并行垃圾清理,速度比Serial有一定的提升。單個(gè)CPU環(huán)境中,存在線程交互開(kāi)銷,不會(huì)比Serail收集器有更好的效果。

Parallel Scavenge

新生代多線程并行收集器
新生代Parallel Scavenge,采用復(fù)制算法
老年代Parallel Old,才用標(biāo)記整理算法
參數(shù)
-XX:+UseParallelGC 使用Parallel收集器+ 老年代串行
-XX:+UseParallelOldGC 新生代和老年代都使用并行收集器
-XX:GCTimeRadio 設(shè)置吞吐量大小
-XX:MaxGCPauseMillis 設(shè)置最大GC停頓時(shí)間
-XX:+UseAdaptiveSizePolicy 開(kāi)啟GC 自適應(yīng)的調(diào)節(jié)策略。

特點(diǎn)

  1. 在進(jìn)行垃圾收集時(shí),必須暫停其他所有工作線程;
  2. 并行多線程
  3. 追求高吞吐量。CMS等收集器的關(guān)注點(diǎn)更多的是用戶線程的停頓時(shí)間(提高用戶體驗(yàn)),而Parallel Scavenge關(guān)注的是吞吐量(用戶線程時(shí)間/(用戶線程時(shí)間+GC線程時(shí)間))。
  4. server模式下,默認(rèn)采用Parallel Scavenge收集器
  5. 自適應(yīng)的調(diào)節(jié)策略。只要設(shè)置最大堆(-Xmx)和MaxGCPauseMillis或GCTimeRadio,收集器會(huì)自動(dòng)調(diào)整新生代的大小、Eden和Survior的比例、對(duì)象進(jìn)入老年代的年齡,以最大程度上接近我們?cè)O(shè)置的MaxGCPauseMillis或GCTimeRadio

CMS

以最短回收停頓時(shí)間為目標(biāo)的多線程并發(fā)收集器
新生代:不可用
老年代:Concurrent Mark Sweep,采用標(biāo)記清除算法
參數(shù)
-XX:+UseConcMarkSweepGC 開(kāi)啟CMS收集器
-XX:+ UseCMSCompactAtFullCollection 默認(rèn)開(kāi)啟。并發(fā)收集頂不住進(jìn)行Full GC后(CMS并發(fā)GC不是“full GC”),進(jìn)行一次碎片整理。整理過(guò)程是獨(dú)占的,會(huì)引起停頓時(shí)間變長(zhǎng)
-XX:CMSFullGCsBeforeCompaction 在上一次壓縮后,再執(zhí)行多少次不壓縮的full GC后,才會(huì)做壓縮。默認(rèn)是0,也就是在默認(rèn)配置下每次CMS GC頂不住了而要轉(zhuǎn)入full GC的時(shí)候都會(huì)做壓縮
-XX:CMSInitiatingOccupancyFraction 內(nèi)存占用率達(dá)到多少的時(shí)候開(kāi)始CMS收集
-XX:+UseCMSInitiatingOccupancyOnly 設(shè)定回收閾值(CMSInitiatingOccupancyFraction指定),如果不指定,JVM僅在第一次使用設(shè)定值,后續(xù)則自動(dòng)調(diào)整.
-XX:ParallelCMSThreads:并行收集時(shí)的線程數(shù)

步驟

  1. 初始標(biāo)記
    暫停所有的其他線程,初始標(biāo)記僅僅標(biāo)記GC Roots能直接關(guān)聯(lián)到的對(duì)象,速度很快
  2. 并發(fā)標(biāo)記
    進(jìn)行GC Roots Tracing的過(guò)程
  3. 重新標(biāo)記
    暫停所有的其他線程,修正并發(fā)標(biāo)記期間用戶程序繼續(xù)運(yùn)行產(chǎn)生變動(dòng)的部分對(duì)象的標(biāo)記記錄(采用多線程并行執(zhí)行來(lái)提升效率)
  4. 并發(fā)清除
    開(kāi)啟用戶線程,同時(shí)GC線程開(kāi)始對(duì)為標(biāo)記的區(qū)域做清掃,回收所有的垃圾對(duì)象

特點(diǎn)

  1. 初始標(biāo)記、重新標(biāo)記兩個(gè)階段必須暫停其他所有工作線程;
  2. 并發(fā)多線程。
  3. 追求高響應(yīng)速度。希望系統(tǒng)停頓時(shí)間最短,以給用戶帶來(lái)較好的體驗(yàn)

缺點(diǎn)

  1. CPU資源敏感?;厥站€程占用一定線程資源,吞吐量下降,默認(rèn)回收線程數(shù)是(CPU數(shù)+3)/4。
  2. 無(wú)法處理浮動(dòng)垃圾。在并發(fā)清除時(shí),用戶線程新產(chǎn)生的垃圾,稱為浮動(dòng)垃圾。可能出現(xiàn)“Concurrent Mode Failure”而導(dǎo)致另一次Full GC。因此CMS不能像其他收集器那樣等到老年代幾乎填滿再進(jìn)行收集,需要預(yù)留一部分空間提供并發(fā)收集期間程序運(yùn)行使用。JDK1.5時(shí),空間使用68%后CMS會(huì)被激活(JDK1.6后為92%)。如果收集期間內(nèi)存不足,則會(huì)出現(xiàn)“Concurrent Mode Failure”失敗,臨時(shí)啟用Serial Old收集器。
  3. 空間碎片。CMS是基于“標(biāo)記+清除”算法來(lái)回收老年代對(duì)象的,因此長(zhǎng)時(shí)間運(yùn)行后會(huì)產(chǎn)生大量的空間碎片問(wèn)題。

內(nèi)存模型

JDK1.8

Young : Old = 1:2
Eden區(qū):Survivor區(qū) = 8:1
收集過(guò)程

  1. 對(duì)象首先在Eden中分配
  2. 如果Eden區(qū)空間不足了,進(jìn)行一次Minor GC,把Eden區(qū)的存活對(duì)象轉(zhuǎn)移到其中一個(gè)Survivor區(qū)(稱為From區(qū)),非存活對(duì)象進(jìn)行清理,然后在Eden區(qū)給新創(chuàng)建的對(duì)象分配空間
  3. 隨著對(duì)象的增多,Eden區(qū)空間又不足了,進(jìn)行一次Minor GC,把Eden區(qū)和From區(qū)的存活對(duì)象轉(zhuǎn)移到另一個(gè)Survivor區(qū)(稱為To區(qū)),非存活對(duì)象進(jìn)行清理,然后From變成To,To變成From,然后在Eden區(qū)給新創(chuàng)建的對(duì)象分配空間
  4. 進(jìn)入老年代
    4.1 To區(qū)空間不足,將存活對(duì)象移入老年代
    4.2 大對(duì)象直接進(jìn)入老年代(PretenureSizeThreshold指定,默認(rèn)3M)
    4.3 長(zhǎng)期存活對(duì)象移入老年代,每經(jīng)過(guò)一次Minor GC年齡加1。年齡增加到一定程度(MaxTenuringThreshold指定,默認(rèn)15)移入老年代
    4.4 From空間中,相同年齡所有對(duì)象的大小總和大于From空間總和的一半
  5. 如果進(jìn)入老年代時(shí),老年代空間不足進(jìn)行Full GC。

參數(shù)
-XX:PretenureSizeThreshold 大于這個(gè)值得對(duì)象直接進(jìn)入老年代,避免新生代發(fā)生大量復(fù)制
-XX:MaxTenuringThreshold 晉升老年代的年齡
-XX:MetaspaceSize Metaspace擴(kuò)容時(shí)觸發(fā)FullGC的初始化閾值
-Xms 初始分配的堆內(nèi)存,默認(rèn)是物理內(nèi)存的1/64
-Xmx最大分配的堆內(nèi)存,默認(rèn)是物理內(nèi)存的1/4

最后編輯于
?著作權(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)容