評(píng)價(jià)GC算法的指標(biāo)和GC原理

吞吐量

垃圾回收算法(6 個(gè)字太長(zhǎng)了哥牍,以下簡(jiǎn)稱 GC)算是對(duì)程序完成它想做的事情的一種輔助毕泌,并不是程序的主要目的(廢話)。所以 GC 占用的時(shí)間越少越好嗅辣,程序花在正事上面的時(shí)間越多越好撼泛。

這個(gè)指標(biāo)其實(shí)很好理解。舉個(gè)例子吧澡谭,標(biāo)記清除算法要遍歷兩次愿题,第一次遍歷所有活躍的對(duì)象,將它們標(biāo)記為“不是垃圾”。第二次遍歷所有的對(duì)象潘酗,將沒(méi)有被標(biāo)記的垃圾回收掉杆兵。復(fù)制收集算法只需要遍歷一次,將活躍的對(duì)象從內(nèi)存的一般復(fù)制到另一半仔夺。所以從這個(gè)指標(biāo)的角度講琐脏,復(fù)制收集算法完爆標(biāo)記清除。

但實(shí)際上缸兔,這個(gè)指標(biāo)是不能“靜態(tài)衡量”的日裙。依然是上面兩種算法,標(biāo)記清除遍歷的時(shí)候速度很快惰蜜,只要寫(xiě)一個(gè)標(biāo)記就可以了昂拂。而復(fù)制收集算法要有 copy 操作。隨著堆中活動(dòng)對(duì)象的增加抛猖,甚至?xí)霈F(xiàn)復(fù)制收集吞吐量小于標(biāo)記清除的情況格侯。

內(nèi)存使用率

這個(gè)指標(biāo)也比較好理解,GC 算法需要一些標(biāo)記樟结,但是如果算法本身所使用的內(nèi)存占得很多养交,就得不償失了。這個(gè)算法本身的目的就是回收內(nèi)存瓢宦,本身卻占用了很多內(nèi)存碎连,聽(tīng)起來(lái)就不合理。

其實(shí)驮履,從算法的角度講鱼辙,內(nèi)存是空間,吞吐量是時(shí)間玫镐。算法上有“用空間換時(shí)間”的策略倒戏,自然 GC 也會(huì)有。這是一種 Trade off恐似,很多情況不可兼得杜跷。

拿引用計(jì)數(shù)來(lái)說(shuō),用幾個(gè)位來(lái)表示引用計(jì)數(shù)是門(mén)學(xué)問(wèn)矫夷。簡(jiǎn)單的話葛闷,占用 8 個(gè)位表示,那每個(gè)對(duì)象 1byte 就沒(méi)有了双藕。假設(shè)是占用 2 個(gè)字節(jié)的對(duì)象淑趾,那么內(nèi)存占用就擴(kuò)大了整整 1.5 倍。 而大多數(shù)對(duì)象僅僅會(huì)被引用 1 次而已忧陪。所以引用計(jì)數(shù)方法就發(fā)展出一些優(yōu)化措施扣泊,減少引用計(jì)數(shù)占用的內(nèi)存近范,配合其他算法來(lái)處理計(jì)數(shù)器溢出的問(wèn)題。有一種極端的方式是只使用 1 位來(lái)計(jì)數(shù)(倒不如說(shuō)這是一種標(biāo)記了)延蟹。

最大暫停時(shí)間

這個(gè)指標(biāo)和“吞吐量”看起來(lái)有些像评矩,GC 算法速度越快,時(shí)間就越小等孵。但是吞吐量指的是總體的速度稚照,最大暫停時(shí)間指的是 GC 算法執(zhí)行的時(shí)候蹂空,程序在等待 GC 完成的最大時(shí)間俯萌。這段時(shí)間由于 GC 的運(yùn)行程序無(wú)法做其他的事情。

為什么這個(gè)指標(biāo)會(huì)重要呢上枕?有些程序可能可以忍受吞吐量不高咐熙,但是實(shí)時(shí)性要求很強(qiáng)的。比如說(shuō)辨萍,A 算法每分鐘暫停 1 次棋恼,一次暫停 1 秒,一小時(shí)一共暫停 60s锈玉。另一個(gè) B 算法每小時(shí)暫停 1 次爪飘,一次暫停 30s±常可想而知师崎,如果是用戶程序暫停時(shí)間長(zhǎng)是體驗(yàn)很糟糕的,另外比如機(jī)器人控制程序椅棺,邁開(kāi)一只腿這時(shí)候到了暫停時(shí)間犁罩,機(jī)器人就摔倒了。

引用計(jì)數(shù)的最大暫停時(shí)間是最好的两疚,因?yàn)閷?duì)象的引用到 0 的時(shí)候立即會(huì)回收床估,這個(gè)過(guò)程不需要暫停程序。而復(fù)制算法和標(biāo)記清除算法需要在無(wú)法申請(qǐng)出更多內(nèi)存的時(shí)候诱渤,暫停程序丐巫,開(kāi)始清除階段/復(fù)制階段。

連續(xù)性(緩存友好程度)

我們知道勺美,越快的存儲(chǔ)價(jià)格就越高递胧。CPU 寄存器速度最快,但是只有幾個(gè)寄存器励烦。高速緩存非澄阶牛快,但是極其昂貴坛掠。然后是內(nèi)存赊锚、硬盤(pán)等治筒。

如果程序在執(zhí)行的時(shí)候緩存命中率高,那么運(yùn)行效率就會(huì)高舷蒲。

在這篇文章中耸袜,我們可以將程序粗略的分成兩部分:GC 運(yùn)行的部分和程序運(yùn)行的部分。如果 GC 運(yùn)行的時(shí)候需要頻繁尋找對(duì)象牲平,然后對(duì)象的引用又在很遠(yuǎn)的地方堤框,那么緩存命中率就會(huì)很低;另一方面說(shuō)纵柿,如果 GC 算法將程序的對(duì)象變得很離散蜈抓,那么程序在運(yùn)行的時(shí)候,互相引用的對(duì)象離得很遠(yuǎn)昂儒,效率就會(huì)很低沟使。

標(biāo)記清除算法會(huì)造成內(nèi)存的碎片,對(duì)緩存不友好渊跋。復(fù)制收集算法由于是拷貝不是垃圾的對(duì)象腊嗡,所以在一次拷貝操作之后,垃圾對(duì)象被釋放拾酝,非垃圾對(duì)象都在一起了燕少,所以命中率會(huì)高。另外上面提到的 1 位引用計(jì)數(shù)算法由于只拷貝指針蒿囤,而不需要去找到對(duì)象客们,所以緩存命令率也會(huì)高。

GC基礎(chǔ)原理

1 GC調(diào)優(yōu)目標(biāo)

大多數(shù)情況下對(duì) Java 程序進(jìn)行GC調(diào)優(yōu), 主要關(guān)注兩個(gè)目標(biāo):響應(yīng)速度蟋软、吞吐量

響應(yīng)速度(Responsiveness)
響應(yīng)速度指程序或系統(tǒng)對(duì)一個(gè)請(qǐng)求的響應(yīng)有多迅速镶摘。比如,用戶訂單查詢響應(yīng)時(shí)間岳守,對(duì)響應(yīng)速度要求很高的系統(tǒng)凄敢,較大的停頓時(shí)間是不可接受的。調(diào)優(yōu)的重點(diǎn)是在短的時(shí)間內(nèi)快速響應(yīng)

吞吐量(Throughput)
吞吐量關(guān)注在一個(gè)特定時(shí)間段內(nèi)應(yīng)用系統(tǒng)的最大工作量湿痢,例如每小時(shí)批處理系統(tǒng)能完成的任務(wù)數(shù)量涝缝,在吞吐量方面優(yōu)化的系統(tǒng),較長(zhǎng)的GC停頓時(shí)間也是可以接受的譬重,因?yàn)楦咄掏铝繎?yīng)用更關(guān)心的是如何盡可能快地完成整個(gè)任務(wù)拒逮,不考慮快速響應(yīng)用戶請(qǐng)求

GC調(diào)優(yōu)中,GC導(dǎo)致的應(yīng)用暫停時(shí)間影響系統(tǒng)響應(yīng)速度臀规,GC處理線程的CPU使用率影響系統(tǒng)吞吐量

2 GC分代收集算法

現(xiàn)代的垃圾收集器基本都是采用分代收集算法滩援,其主要思想: 將Java的堆內(nèi)存邏輯上分成兩塊:新生代、老年代塔嬉,針對(duì)不同存活周期玩徊、不同大小的對(duì)象采取不同的垃圾回收策略

image.png
  • 新生代(Young Generation)

新生代又叫年輕代租悄,大多數(shù)對(duì)象在新生代中被創(chuàng)建,很多對(duì)象的生命周期很短恩袱。每次新生代的垃圾回收(又稱Young GC泣棋、Minor GC、YGC)后只有少量對(duì)象存活畔塔,所以使用復(fù)制算法潭辈,只需少量的復(fù)制操作成本就可以完成回收.

新生代內(nèi)又分三個(gè)區(qū):一個(gè)Eden區(qū),兩個(gè)Survivor區(qū)(S0澈吨、S1把敢,又稱From Survivor、To Survivor)棚辽,大部分對(duì)象在Eden區(qū)中生成技竟。當(dāng)Eden區(qū)滿時(shí),還存活的對(duì)象將被復(fù)制到兩個(gè)Survivor區(qū)(中的一個(gè))屈藐。當(dāng)這個(gè)Survivor區(qū)滿時(shí),此區(qū)的存活且不滿足晉升到老年代條件的對(duì)象將被復(fù)制到另外一個(gè)Survivor區(qū)熙尉。對(duì)象每經(jīng)歷一次復(fù)制联逻,年齡加1,達(dá)到晉升年齡閾值后检痰,轉(zhuǎn)移到老年代

老年代(Old Generation)
在新生代中經(jīng)歷了N次垃圾回收后仍然存活的對(duì)象包归,就會(huì)被放到老年代,該區(qū)域中對(duì)象存活率高铅歼。老年代的垃圾回收通常使用“標(biāo)記-整理”算法

3 GC事件分類(lèi)

根據(jù)垃圾收集回收的區(qū)域不同公壤,垃圾收集主要通常分為Young GC、Old GC椎椰、Full GC厦幅、Mixed GC
(1) Young GC
新生代內(nèi)存的垃圾收集事件稱為Young GC(又稱Minor GC),當(dāng)JVM無(wú)法為新對(duì)象分配在新生代內(nèi)存空間時(shí)總會(huì)觸發(fā) Young GC慨飘,比如 Eden 區(qū)占滿時(shí)确憨。新對(duì)象分配頻率越高, Young GC 的頻率就越高

Young GC 每次都會(huì)引起全線停頓(Stop-The-World),暫停所有的應(yīng)用線程瓤的,停頓時(shí)間相對(duì)老年代GC的造成的停頓休弃,幾乎可以忽略不計(jì)

Old GC,只清理老年代空間的GC事件圈膏,只有CMS的并發(fā)收集是這個(gè)模式
Full GC塔猾,清理整個(gè)堆的GC事件,包括新生代稽坤、老年代丈甸、元空間等

Mixed GC医增,清理整個(gè)新生代以及部分老年代的GC,只有G1有這個(gè)模式

GC日志分析

GC日志是一個(gè)很重要的工具老虫,它準(zhǔn)確記錄了每一次的GC的執(zhí)行時(shí)間和執(zhí)行結(jié)果叶骨,通過(guò)分析GC日志可以調(diào)優(yōu)堆設(shè)置和GC設(shè)置,或者改進(jìn)應(yīng)用程序的對(duì)象分配模式祈匙,開(kāi)啟的JVM啟動(dòng)參數(shù)如下:

-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps  -XX:+PrintGCTimeStamps

常見(jiàn)的Young GC忽刽、Full GC日志含義如下:

image.png

image.png

免費(fèi)的GC日志圖形分析工具推薦下面2個(gè):

  • GCViewer,下載jar包直接運(yùn)行
  • gceasy夺欲,web工具跪帝,上傳GC日志在線使用
5 內(nèi)存分配策略

Java提供的自動(dòng)內(nèi)存管理,可以歸結(jié)為解決了對(duì)象的內(nèi)存分配和回收的問(wèn)題些阅,前面已經(jīng)介紹了內(nèi)存回收伞剑,下面介紹幾條最普遍的內(nèi)存分配策略

對(duì)象優(yōu)先在Eden區(qū)分配
大多數(shù)情況下,對(duì)象在先新生代Eden區(qū)中分配市埋。當(dāng)Eden區(qū)沒(méi)有足夠空間進(jìn)行分配時(shí)黎泣,虛擬機(jī)將發(fā)起一次Young GC

大對(duì)象直接進(jìn)入老年代
JVM提供了一個(gè)對(duì)象大小閾值參數(shù)(-XX:PretenureSizeThreshold,默認(rèn)值為0缤谎,代表不管多大都是先在Eden中分配內(nèi)存)抒倚,大于參數(shù)設(shè)置的閾值值的對(duì)象直接在老年代分配,這樣可以避免對(duì)象在Eden及兩個(gè)Survivor直接發(fā)生大內(nèi)存復(fù)制

長(zhǎng)期存活的對(duì)象將進(jìn)入老年代
對(duì)象每經(jīng)歷一次垃圾回收坷澡,且沒(méi)被回收掉托呕,它的年齡就增加1,大于年齡閾值參數(shù)(-XX:MaxTenuringThreshold频敛,默認(rèn)15)的對(duì)象项郊,將晉升到老年代中

空間分配擔(dān)保
當(dāng)進(jìn)行Young GC之前,JVM需要預(yù)估:老年代是否能夠容納Young GC后新生代晉升到老年代的存活對(duì)象斟赚,以確定是否需要提前觸發(fā)GC回收老年代空間着降,基于空間分配擔(dān)保策略來(lái)計(jì)算:

continueSize:老年代最大可用連續(xù)空間

image.png

Young GC之后如果成功(Young GC后晉升對(duì)象能放入老年代),則代表?yè)?dān)保成功汁展,不用再進(jìn)行Full GC鹊碍,提高性能;如果失敗食绿,則會(huì)出現(xiàn)“promotion failed”錯(cuò)誤侈咕,代表?yè)?dān)保失敗,需要進(jìn)行Full GC
動(dòng)態(tài)年齡判定
新生代對(duì)象的年齡可能沒(méi)達(dá)到閾值(MaxTenuringThreshold參數(shù)指定)就晉升老年代器紧,如果Young GC之后耀销,新生代存活對(duì)象達(dá)到相同年齡所有對(duì)象大小的總和大于任一Survivor空間(S0 或 S1總空間)的一半,此時(shí)S0或者S1區(qū)即將容納不了存活的新生代對(duì)象铲汪,年齡大于或等于該年齡的對(duì)象就可以直接進(jìn)入老年代熊尉,無(wú)須等到MaxTenuringThreshold中要求的年齡

另外罐柳,如果Young GC后S0或S1區(qū)不足以容納:未達(dá)到晉升老年代條件的新生代存活對(duì)象,會(huì)導(dǎo)致這些存活對(duì)象直接進(jìn)入老年代狰住,需要盡量避免

CMS原理及調(diào)優(yōu)

1 名詞解釋
  • 可達(dá)性分析算法:用于判斷對(duì)象是否存活张吉,基本思想是通過(guò)一系列稱為“GC Root”的對(duì)象作為起點(diǎn)(常見(jiàn)的GC Root有系統(tǒng)類(lèi)加載器、棧中的對(duì)象催植、處于激活狀態(tài)的線程等)肮蛹,基于對(duì)象引用關(guān)系,從GC Roots開(kāi)始向下搜索创南,所走過(guò)的路徑稱為引用鏈伦忠,當(dāng)一個(gè)對(duì)象到GC Root沒(méi)有任何引用鏈相連,證明對(duì)象不再存活
  • Stop The World:GC過(guò)程中分析對(duì)象引用關(guān)系稿辙,為了保證分析結(jié)果的準(zhǔn)確性昆码,需要通過(guò)停頓所有Java執(zhí)行線程,保證引用關(guān)系不再動(dòng)態(tài)變化邻储,該停頓事件稱為Stop The World(STW)
  • Safepoint:代碼執(zhí)行過(guò)程中的一些特殊位置赋咽,當(dāng)線程執(zhí)行到這些位置的時(shí)候,說(shuō)明虛擬機(jī)當(dāng)前的狀態(tài)是安全的芥备,如果有需要GC冬耿,線程可以在這個(gè)位置暫停。HotSpot采用主動(dòng)中斷的方式萌壳,讓執(zhí)行線程在運(yùn)行期輪詢是否需要暫停的標(biāo)志,若需要?jiǎng)t中斷掛起
2 CMS簡(jiǎn)介

CMS(Concurrent Mark and Sweep 并發(fā)-標(biāo)記-清除)日月,是一款基于并發(fā)袱瓮、使用標(biāo)記清除算法的垃圾回收算法,只針對(duì)老年代進(jìn)行垃圾回收爱咬。CMS收集器工作時(shí)尺借,盡可能讓GC線程和用戶線程并發(fā)執(zhí)行,以達(dá)到降低STW時(shí)間的目的
通過(guò)以下命令行參數(shù)精拟,啟用CMS垃圾收集器:

-XX:+UseConcMarkSweepGC

值得補(bǔ)充的是燎斩,下面介紹到的CMS GC是指老年代的GC,而Full GC指的是整個(gè)堆的GC事件蜂绎,包括新生代栅表、老年代、元空間等师枣,兩者有所區(qū)分

3 新生代垃圾回收

能與CMS搭配使用的新生代垃圾收集器有Serial收集器和ParNew收集器怪瓶。這2個(gè)收集器都采用標(biāo)記復(fù)制算法,都會(huì)觸發(fā)STW事件践美,停止所有的應(yīng)用線程洗贰。不同之處在于找岖,Serial是單線程執(zhí)行,ParNew是多線程執(zhí)行

image.png
4 老年代垃圾回收

CMS GC以獲取最小停頓時(shí)間為目的敛滋,盡可能減少STW時(shí)間许布,可以分為7個(gè)階段


image.png

階段 1: 初始標(biāo)記(Initial Mark)

此階段的目標(biāo)是標(biāo)記老年代中所有存活的對(duì)象, 包括 GC Root 的直接引用, 以及由新生代中存活對(duì)象所引用的對(duì)象,觸發(fā)第一次STW事件
這個(gè)過(guò)程是支持多線程的(JDK7之前單線程绎晃,JDK8之后并行蜜唾,可通過(guò)參數(shù)CMSParallelInitialMarkEnabled調(diào)整)

image.png
image.png

階段 2: 并發(fā)標(biāo)記(Concurrent Mark)
此階段GC線程和應(yīng)用線程并發(fā)執(zhí)行,遍歷階段1初始標(biāo)記出來(lái)的存活對(duì)象箕昭,然后繼續(xù)遞歸標(biāo)記這些對(duì)象可達(dá)的對(duì)象

image.png

階段 3: 并發(fā)預(yù)清理(Concurrent Preclean)

此階段GC線程和應(yīng)用線程也是并發(fā)執(zhí)行灵妨,因?yàn)殡A段2是與應(yīng)用線程并發(fā)執(zhí)行,可能有些引用關(guān)系已經(jīng)發(fā)生改變落竹。
通過(guò)卡片標(biāo)記(Card Marking)泌霍,提前把老年代空間邏輯劃分為相等大小的區(qū)域(Card),如果引用關(guān)系發(fā)生改變述召,JVM會(huì)將發(fā)生改變的區(qū)域標(biāo)記位“臟區(qū)”(Dirty Card)朱转,然后在本階段,這些臟區(qū)會(huì)被找出來(lái)积暖,刷新引用關(guān)系藤为,清除“臟區(qū)”標(biāo)記

image.png

階段 4: 并發(fā)可取消的預(yù)清理(Concurrent Abortable Preclean)

此階段也不停止應(yīng)用線程. 本階段嘗試在 STW 的 最終標(biāo)記階段(Final Remark)之前盡可能地多做一些工作,以減少應(yīng)用暫停時(shí)間
在該階段不斷循環(huán)處理:標(biāo)記老年代的可達(dá)對(duì)象夺刑、掃描處理Dirty Card區(qū)域中的對(duì)象缅疟,循環(huán)的終止條件有:
1 達(dá)到循環(huán)次數(shù)
2 達(dá)到循環(huán)執(zhí)行時(shí)間閾值
3 新生代內(nèi)存使用率達(dá)到閾值

階段 5: 最終標(biāo)記(Final Remark)

這是GC事件中第二次(也是最后一次)STW階段,目標(biāo)是完成老年代中所有存活對(duì)象的標(biāo)記遍愿。在此階段執(zhí)行:
1 遍歷新生代對(duì)象存淫,重新標(biāo)記
2 根據(jù)GC Roots,重新標(biāo)記
3 遍歷老年代的Dirty Card沼填,重新標(biāo)記

階段 6: 并發(fā)清除(Concurrent Sweep)

此階段與應(yīng)用程序并發(fā)執(zhí)行桅咆,不需要STW停頓,根據(jù)標(biāo)記結(jié)果清除垃圾對(duì)象


image.png

階段 7: 并發(fā)重置(Concurrent Reset)
此階段與應(yīng)用程序并發(fā)執(zhí)行坞笙,重置CMS算法相關(guān)的內(nèi)部數(shù)據(jù), 為下一次GC循環(huán)做準(zhǔn)備

5 CMS常見(jiàn)問(wèn)題

最終標(biāo)記階段停頓時(shí)間過(guò)長(zhǎng)問(wèn)題
CMS的GC停頓時(shí)間約80%都在最終標(biāo)記階段(Final Remark)岩饼,若該階段停頓時(shí)間過(guò)長(zhǎng),常見(jiàn)原因是新生代對(duì)老年代的無(wú)效引用薛夜,在上一階段的并發(fā)可取消預(yù)清理階段中籍茧,執(zhí)行閾值時(shí)間內(nèi)未完成循環(huán),來(lái)不及觸發(fā)Young GC却邓,清理這些無(wú)效引用
通過(guò)添加參數(shù):-XX:+CMSScavengeBeforeRemark硕糊。在執(zhí)行最終操作之前先觸發(fā)Young GC,從而減少新生代對(duì)老年代的無(wú)效引用,降低最終標(biāo)記階段的停頓简十,但如果在上個(gè)階段(并發(fā)可取消的預(yù)清理)已觸發(fā)Young GC檬某,也會(huì)重復(fù)觸發(fā)Young GC

并發(fā)模式失敗(concurrent mode failure) & 晉升失敗(promotion failed)問(wèn)題

image.png

并發(fā)模式失敗:當(dāng)CMS在執(zhí)行回收時(shí)螟蝙,新生代發(fā)生垃圾回收恢恼,同時(shí)老年代又沒(méi)有足夠的空間容納晉升的對(duì)象時(shí),CMS 垃圾回收就會(huì)退化成單線程的Full GC胰默。所有的應(yīng)用線程都會(huì)被暫停场斑,老年代中所有的無(wú)效對(duì)象都被回收

image.png

晉升失敗:當(dāng)新生代發(fā)生垃圾回收牵署,老年代有足夠的空間可以容納晉升的對(duì)象漏隐,但是由于空閑空間的碎片化,導(dǎo)致晉升失敗奴迅,此時(shí)會(huì)觸發(fā)單線程且?guī)嚎s動(dòng)作的Full GC

并發(fā)模式失敗和晉升失敗都會(huì)導(dǎo)致長(zhǎng)時(shí)間的停頓青责,常見(jiàn)解決思路如下:

  • 降低觸發(fā)CMS GC的閾值,即參數(shù)-XX:CMSInitiatingOccupancyFraction的值取具,讓CMS GC盡早執(zhí)行脖隶,以保證有足夠的空間
  • 增加CMS線程數(shù),即參數(shù)-XX:ConcGCThreads暇检,
  • 增大老年代空間
  • 讓對(duì)象盡量在新生代回收产阱,避免進(jìn)入老年代

內(nèi)存碎片問(wèn)題
通常CMS的GC過(guò)程基于標(biāo)記清除算法,不帶壓縮動(dòng)作块仆,導(dǎo)致越來(lái)越多的內(nèi)存碎片需要壓縮构蹬,常見(jiàn)以下場(chǎng)景會(huì)觸發(fā)內(nèi)存碎片壓縮:

  • 新生代Young GC出現(xiàn)新生代晉升擔(dān)保失敗(promotion failed)
  • 程序主動(dòng)執(zhí)行System.gc()

可通過(guò)參數(shù)CMSFullGCsBeforeCompaction的值,設(shè)置多少次Full GC觸發(fā)一次壓縮悔据,默認(rèn)值為0怎燥,代表每次進(jìn)入Full GC都會(huì)觸發(fā)壓縮,帶壓縮動(dòng)作的算法為上面提到的單線程Serial Old算法蜜暑,暫停時(shí)間(STW)時(shí)間非常長(zhǎng),需要盡可能減少壓縮時(shí)間

G1原理及調(diào)優(yōu)

G1(Garbage-First)是一款面向服務(wù)器的垃圾收集器策肝,支持新生代和老年代空間的垃圾收集肛捍,主要針對(duì)配備多核處理器及大容量?jī)?nèi)存的機(jī)器,G1最主要的設(shè)計(jì)目標(biāo)是: 實(shí)現(xiàn)可預(yù)期及可配置的STW停頓時(shí)間

2 G1堆空間劃分
image.png

Region

為實(shí)現(xiàn)大內(nèi)存空間的低停頓時(shí)間的回收之众,將劃分為多個(gè)大小相等的Region拙毫。每個(gè)小堆區(qū)都可能是 Eden區(qū),Survivor區(qū)或者Old區(qū)棺禾,但是在同一時(shí)刻只能屬于某個(gè)代
在邏輯上, 所有的Eden區(qū)和Survivor區(qū)合起來(lái)就是新生代缀蹄,所有的Old區(qū)合起來(lái)就是老年代,且新生代和老年代各自的內(nèi)存Region區(qū)域由G1自動(dòng)控制,不斷變動(dòng)

巨型對(duì)象

當(dāng)對(duì)象大小超過(guò)Region的一半缺前,則認(rèn)為是巨型對(duì)象(Humongous Object)蛀醉,直接被分配到老年代的巨型對(duì)象區(qū)(Humongous regions),這些巨型區(qū)域是一個(gè)連續(xù)的區(qū)域集衅码,每一個(gè)Region中最多有一個(gè)巨型對(duì)象拯刁,巨型對(duì)象可以占多個(gè)Region
G1把堆內(nèi)存劃分成一個(gè)個(gè)Region的意義在于:

每次GC不必都去處理整個(gè)堆空間,而是每次只處理一部分Region逝段,實(shí)現(xiàn)大容量?jī)?nèi)存的GC
通過(guò)計(jì)算每個(gè)Region的回收價(jià)值垛玻,包括回收所需時(shí)間、可回收空間奶躯,在有限時(shí)間內(nèi)盡可能回收更多的內(nèi)存帚桩,把垃圾回收造成的停頓時(shí)間控制在預(yù)期配置的時(shí)間范圍內(nèi),這也是G1名稱的由來(lái): garbage-first

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末嘹黔,一起剝皮案震驚了整個(gè)濱河市账嚎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌参淹,老刑警劉巖醉锄,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異浙值,居然都是意外死亡恳不,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)开呐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)烟勋,“玉大人,你說(shuō)我怎么就攤上這事筐付÷训耄” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵瓦戚,是天一觀的道長(zhǎng)沮尿。 經(jīng)常有香客問(wèn)我,道長(zhǎng)较解,這世上最難降的妖魔是什么畜疾? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮印衔,結(jié)果婚禮上啡捶,老公的妹妹穿的比我還像新娘。我一直安慰自己奸焙,他們只是感情好瞎暑,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布彤敛。 她就那樣靜靜地躺著,像睡著了一般了赌。 火紅的嫁衣襯著肌膚如雪墨榄。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天揍拆,我揣著相機(jī)與錄音渠概,去河邊找鬼。 笑死嫂拴,一個(gè)胖子當(dāng)著我的面吹牛播揪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播筒狠,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼猪狈,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了辩恼?” 一聲冷哼從身側(cè)響起雇庙,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎灶伊,沒(méi)想到半個(gè)月后疆前,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡聘萨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年竹椒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片米辐。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡胸完,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出翘贮,到底是詐尸還是另有隱情赊窥,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布狸页,位于F島的核電站锨能,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏芍耘。R本人自食惡果不足惜腹侣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望齿穗。 院中可真熱鬧,春花似錦饺律、人聲如沸窃页。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)脖卖。三九已至乒省,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間畦木,已是汗流浹背袖扛。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留十籍,地道東北人蛆封。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像勾栗,于是被迫代替她去往敵國(guó)和親惨篱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345