是不是才聽說了JDK11的ZGC,并且還沒搞懂?不好意思,OpenJDK12馬不停蹄的帶來了Shenandoah GC。
10多年的湞江網站建設經驗,針對設計、前端、開發、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。成都營銷網站建設的優勢是能夠根據用戶設備顯示端的尺寸不同,自動調整湞江建站的顯示方式,使網站能夠適用不同顯示終端,在瀏覽器中調整網站的寬度,無論在任何一種瀏覽器上瀏覽網站,都能展現優雅布局與設計,從而大程度地提升瀏覽體驗。創新互聯從事“湞江網站設計”,“湞江網站推廣”以來,每個客戶項目都認真落實執行。JDK12新增的一個名為Shenandoah的GC算法,它的evacuation階段工作能通過與正在運行中Java工作線程同時進行(即并發,concurrent),從而減少GC的停頓時間。
Shenandoah的停頓時間和堆的大小沒有任何關系,這就意味著無論你的堆是200MB,2GB還是200GB,停頓時間是一樣的。
如上圖所示,Shenandoah GC每個GC周期由2個STW(Stop The World)階段和2個并發階段組成。在初始化標記階段,掃描root集合的時候會STW。然后并發標記階段,Shenandoah GC和Java工作線程一起運行,最后,在最終標記階段,又會STW,然后執行一個并發evacuation階段。
Root集合包括:thread local variables, references embedded in generated code, interned Strings, references from classloaders (e.g. static final references), JNI references, JVMTI references.
Shenandoah是一個基于Region設計的垃圾收集器,這點和G1類似,它把整個堆當作Region集合來維護。但是,Shenandoah不需要remember set或者card table來記錄跨region引用。?
其中一個原因是(無條件)card mark可能引起false sharing,而Brooks pointer分散在每個對象頭上
,比較不容易引起false sharing:
一個常規的Shenandoah GC周期大概是這樣的(跟G1也有點相似):
GC日志如下:
GC(3)?Pause?Init?Mark?0.771msGC(3)?Concurrent?marking?76480M->77212M(102400M)?633.213msGC(3)?Pause?Final?Mark?1.821msGC(3)?Concurrent?cleanup?77224M->66592M(102400M)?3.112msGC(3)?Concurrent?evacuation?66592M->75640M(102400M)?405.312msGC(3)?Pause?Init?Update?Refs?0.084msGC(3)?Concurrent?update?references??75700M->76424M(102400M)?354.341msGC(3)?Pause?Final?Update?Refs?0.409msGC(3)?Concurrent?cleanup?76244M->56620M(102400M)?12.242ms
每個階段要做的事情如下:
Init Mark并發標記的初始化階段,它為并發標記準備堆和應用線程,然后掃描root集合。這是整個GC生命周期第一次停頓,這個階段主要工作是root集合掃描,所以停頓時間主要取決于root集合大小。
Concurrent Marking貫穿整個堆,以root集合為起點,跟蹤可達的所有對象。 這個階段和應用程序一起運行,即并發(concurrent)。這個階段的持續時間主要取決于存活對象的數量,以及堆中對象圖的結構。由于這個階段,應用依然可以分配新的數據,所以在并發標記階段,堆占用率會上升。
Final Mark清空所有待處理的標記/更新隊列,重新掃描root集合,結束并發標記。. 這個階段還會搞明白需要被清理(evacuated)的region(即垃圾收集集合),并且通常為下一階段做準備。最終標記是整個GC周期的第二個停頓階段,這個階段的部分工作能在并發預清理階段完成,這個階段最耗時的還是清空隊列和掃描root集合。
Concurrent Cleanup回收即時垃圾區域 -- 這些區域是指并發標記后,探測不到任何存活的對象。
Concurrent Evacuation從垃圾收集集合中拷貝存活的對到其他的region中,這是有別于OpenJDK其他GC主要的不同點。這個階段能再次和應用一起運行,所以應用依然可以繼續分配內存,這個階段持續時間主要取決于選中的垃圾收集集合大小(比如整個堆劃分128個region,如果有16個region被選中,其耗時肯定超過8個region被選中)。
Init Update Refs初始化更新引用階段,它除了確保所有GC線程和應用線程已經完成并發Evacuation階段,以及為下一階段GC做準備以外,其他什么都沒有做。這是整個GC周期中,第三次停頓,也是時間最短的一次。
Concurrent Update References再次遍歷整個堆,更新那些在并發evacuation階段被移動的對象的引用。這也是有別于OpenJDK其他GC主要的不同,這個階段持續時間主要取決于堆中對象的數量,和對象圖結構無關,因為這個過程是線性掃描堆。這個階段是和應用一起并發運行的。
Final Update Refs通過再次更新現有的root集合完成更新引用階段,它也會回收收集集合中的region,因為現在的堆已經沒有對這些region中的對象的引用。
這是整個GC周期最后一個階段,它的持續時間主要取決于root集合的大小。
Concurrent Cleanup回收那些現在沒有任何引用的Region集合。
Shenandoah不是一個要一統天下的GC,有一些其他的吞吐量優先,或者內存占用優先的GC算法,它們并不是把響應性放在第一位(即不是主要考慮縮短停頓時間)。
Shenandoah是一個對那些更看重響應性和可預測短暫停頓的應用來說,更合適的GC算法。它的目標不是要解決所有JVM的停頓問題,由于GC之外的其他原因(例如到達安全點時間(TTSP--Time To Safe Point)問題)而暫停時間超出了此JEP的范圍。
現代服務器比以前擁有更多的內存和處理器,SLA應用需要保證RP在10~500ms。為了達到
最苛刻的目標(保證RP在10ms以內),我們需要GC的算法足夠高效,允許程序在可用內存中運行,并且經過優化后,永遠不會讓正在運行的程序的停頓時間超過5毫秒(a handful of milliseconds,一只手就5根手指頭,所以是5ms)。
Shenandoah就是這樣一個OpenJDK為更近這個目標而設計的開源、低停頓時間的垃圾回收器。
1. Zing/Azul是一個沒有停頓的垃圾收集器,但是不會貢獻給OpenJDK。
2. 基于colored pointers
設計的ZGC也是一個擁有很低停頓時間的垃圾收集器,Shenandoah期望能與之一戰。
3. G1很多工作都是并行或者并發的,但是evacuation階段不能并發執行。
4. CMS能并發標記,但是它執行年輕代拷貝時,需要STW,并且不會壓縮老年代,這就會導致花費更多時間來管理老年代中的可用空間以及碎片問題。
這還是一個體驗功能,需要增加-XX:+UnlockExperimentalVMOptions參數才能開啟Shenandoah GC:
-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC
RedHat已經做了大量的測試,OpenJDK也為Shenandoah開發了很多測試用例。而且從Fedora 24開始Shenandoah在Fedora中隨著JDK一起發布,并在Rhel7.4中作為技術預覽. 通過-XX:+UseShenandoahGC
運行標準的OpenJDK完全足夠。
關于CMS,G1,ParallelOld,Shenandoah的延遲測試對比,如下圖所示:
創新互聯www.cdcxhl.cn,專業提供香港、美國云服務器,動態BGP最優骨干路由自動選擇,持續穩定高效的網絡助力業務部署。公司持有工信部辦法的idc、isp許可證, 機房獨有T級流量清洗系統配攻擊溯源,準確進行流量調度,確保服務器高可用性。佳節活動現已開啟,新人活動云服務器買多久送多久。
分享標題:ShenandoahGC:一個來自JDK12的全新并發壓縮垃圾回收器-創新互聯
路徑分享:http://m.newbst.com/article36/dsgisg.html
成都網站建設公司_創新互聯,為您提供營銷型網站建設、網站營銷、品牌網站建設、外貿建站、電子商務、移動網站建設
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯