具有超低停頓時間的垃圾回收算法Shenandoah

責(zé)任編輯:editor004

作者:薛命燈

2017-01-11 11:47:08

摘自:INFOQ

總的來說,大部分垃圾回收器要么使用古老的標(biāo)記并清除算法,要么使用分代算法,再結(jié)合并發(fā)和堆壓縮。通過更細(xì)粒度的分區(qū),Shenandoah可以優(yōu)先對包含更多垃圾的區(qū)域進行回收,同時有助于并行回收工作的進行。

早在三年前,Red Hat就啟動了Shenandoah項目。Shenandoah是一種新的Java虛擬機GC算法,目標(biāo)是利用現(xiàn)代多核CPU的優(yōu)勢,減少大堆內(nèi)存在GC方面存在的停頓時間。Shenandoah后來被貢獻給了OpenJDK,正式成為OpenJDK的開源項目,也就是JEP 189。

總的來說,大部分垃圾回收器要么使用古老的標(biāo)記并清除算法,要么使用分代算法,再結(jié)合并發(fā)和堆壓縮。垃圾回收器多種多樣,但沒有一種回收器能夠滿足所有的需求,它們總要在某些方面做出折衷,并且不可避免地存在停頓時間。而Shenandoah最大的兩個特點是它伸縮性和超低停頓時間。

Shenandoah最初的目標(biāo)是把GC停頓時間降到10毫秒以下,并且對內(nèi)存的支持?jǐn)U展到TB級別。為了降低停頓時間,回收器需要使用更多的線程來并行處理回收任務(wù)。而要在降低停頓時間的同時能夠支持更大的堆空間,回收器對CPU的多核處理能力提出了更高的要求。相比于CMS和G1,Shenandoah不僅進行并行的垃圾標(biāo)記,在壓縮堆空間時也是并行進行的。

Shenandoah把堆空間分為很多區(qū)域,例如整個堆空間是1G,如果每個區(qū)域是1M,那么就會有1000多個區(qū)域。傳統(tǒng)的標(biāo)記并清除回收器并沒有區(qū)域的概念,而拷貝回收器一般也只有兩個或少數(shù)幾個區(qū)域。通過更細(xì)粒度的分區(qū),Shenandoah可以優(yōu)先對包含更多垃圾的區(qū)域進行回收,同時有助于并行回收工作的進行。

Shenandoah是一個標(biāo)記拷貝回收器,它的回收工作分為兩個階段。第一個階段是標(biāo)記階段。在這個階段,回收器會對每個區(qū)域里的對象進行標(biāo)記,并計算它們的數(shù)量。第二個階段,回收器對源區(qū)域的對象進行掃描,并把存活對象拷貝到目標(biāo)區(qū)域,然后源區(qū)域的內(nèi)存就可以被釋放。這兩個階段看似很簡單,但要讓整個過程并行進行,從而降低停頓時間,事情就會變得復(fù)雜很多。

到目前為止,Shenandoah已經(jīng)實現(xiàn)了很多特性,包括運行時、解釋器、C1屏障和C2屏障、對弱引用的支持、對JNI臨界區(qū)域的支持、對System.gc()的支持,等等。Shenandoah目前還算穩(wěn)定,它的平均性能能夠達到G1的90%,有時候會差一些,比如70%,不過有時候會超過G1,比如150%。不過Shenandoah的停頓時間比G1要短很多,不過相比之前定下的目標(biāo),還有很大距離。

目前還沒有把Shenandoah用在Java 9里的計劃,不過如果有人對此感興趣,可以自己從源代碼構(gòu)建特別版本的JDK來體驗Shenandoah。關(guān)于更多Shenandoah的細(xì)節(jié)可以在這里看到。

不過,從Shenandoah的目標(biāo)來看,它更適合用在大堆上。所以,如果CPU資源有限,內(nèi)存也不大,比如小于20G,那么就沒有必要使用Shenandoah。

鏈接已復(fù)制,快去分享吧

企業(yè)網(wǎng)版權(quán)所有?2010-2024 京ICP備09108050號-6京公網(wǎng)安備 11010502049343號