日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Oracle即将发布的全新Java垃圾收集器 ZGC

發布時間:2023/12/6 java 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Oracle即将发布的全新Java垃圾收集器 ZGC 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java 11的特性集合已經確定,其中包含了一些非常棒的特性。新版本提供了一個全新的垃圾回收器ZGC,它由甲骨文開發,承諾在TB級別的堆上實現非常低的停頓時間。在本文中,我們將介紹甲骨文開發ZGC的動機、ZGC的技術概覽以及ZGC帶來的一些非常令人興奮的可能性。

\\

那么為什么要開發ZGC?畢竟Java 10中已經帶有4款久經考驗的垃圾回收器。Hotspot最新的垃圾回收器G1是在2006年推出的。當時最大的AWS實例是m1.small,配備1個vCPU和1.7GB內存,而到了今天,AWS提供了x1e.32xlarge實例,配備了128個vCPU和令人難以置信的3,904GB內存。ZGC所針對的是這些在未來普遍存在的大容量內存:TB級別的堆容量,具有很低的停頓時間(小于10毫秒),對整體應用性能的影響也很小(對吞吐量的影響低于15%)。ZGC所采用的機制也可以在未來進行擴展,以支持一些令人興奮的特性,如多層堆(用于熱對象的DRAM和用于低頻訪問對象的NVMe閃存)或壓縮堆。

\\

GC術語

\\

要了解ZGC在現有垃圾回收器中所處的位置,以及它是如何達到這個位置的,我們先需要先了解一些術語。最基本的GC包括識別出不再使用的內存,并將其變為可用的?,F代垃圾回收器通常分幾個階段來完成回收過程,如下所示:

\\
  • 并行(Parallel)——運行中的JVM包含應用程序線程和GC線程。在并行階段,會運行多個GC線程,也就是說任務被拆分給它們去完成。至于GC線程是否可以與正在運行的應用程序線程重疊,這個在規范中并沒有特別說明。\\t
  • 串行(Serial)——串行階段只有單個GC線程在運行。與上面的并行階段一樣,規范中也沒有說明GC線程是否可以與當前運行的應用程序線程重疊。\\t
  • Stop The World(STW)——在這個階段,應用程序線程被暫停,讓GC線程執行它們的任務。當你遇到GC停頓時,說明虛擬機進入了STW階段。\\t
  • 并發(Concurrent)——在并發階段,GC線程可以在運行應用程序線程的同時執行自己的任務。并發階段非常復雜,因為應用程序線程有可能在GC完成之前將其中斷。\\t
  • 增量(Incremental)——在增量階段,它可以運行一段時間,并基于某些條件提前終止,例如時間預算或執行更高優先級的GC階段。\

權衡取舍

\\

需要指出的是,所有這些屬性都存在權衡。例如,并行階段將利用多個GC線程來執行任務,但這樣做會導致協調線程的開銷。同樣,并發階段不會暫停應用程序線程,但可能涉及更多的開銷和復雜性。

\\

ZGC

\\

在了解了GC不同階段的屬性后,現在讓我們來探討ZGC的工作原理。ZGC使用了兩項新技術:彩色指針和加載屏障。

\\

指針著色

\\

指針著色是將信息存儲在指針(或引用)中的一種技術。這是有可能的,因為在64位平臺上(ZGC僅支持64位),指針可以處理比系統實際擁有的內存更大的內存,因此可以使用多余的位來存儲狀態。ZGC將堆限制為4TB,需要42位,剩下的22位當中目前已經使用了4位:finalizable、remap、mark0和mark1。

\\

不過,指針著色也存在一個問題,當你想要取消引用指針時,需要做額外的工作,因為你需要屏蔽掉信息位。SPARC平臺已經為指針屏蔽提供了內置硬件支持,所以這不是什么問題。但x86平臺還沒有提供類似的支持,所以ZGC團隊針對x86平臺使用了多次映射技術。

\\

多次映射

\\

要了解多映射的工作原理,我們需要先簡要地解釋一下虛擬內存和物理內存之間的區別。物理內存是系統可用的實際內存,也就是DRAM芯片的容量。虛擬內存是抽象的,對于應用程序來說,它們有自己的物理內存試圖(通常是隔離的)。操作系統負責維護虛擬內存和物理內存之間的映射,通過使用頁表和處理器的內存管理單元(MMU)以及轉換后備緩沖區(TLB,用于轉換應用程序的請求地址)來實現。

\\

多次映射技術將不同范圍的虛擬內存映射到同一物理內存上。在remap、mark0和mark1當中,同一時間點只能有一個為1,因此可以使用三個映射。ZGC源代碼中提供了一個很直觀的圖表(http://hg.openjdk.java.net/zgc/zgc/file/59c07aef65ac/src/hotspot/os_cpu/linux_x86/zGlobals_linux_x86.hpp#l39)。

\\

加載屏障

\\

加載屏障是一小段代碼,當應用程序線程從堆加載引用時就會運行這段代碼(即訪問對象的非原始類型字段):

\\\void printName( Person person ) {\ String name = person.name; // 將會觸發加載屏障,因為從堆中加載了一個引用\ System.out.println(name); // 沒有直接使用加載屏障\}\\

第一行代碼是給變量name賦值,這需要跟蹤堆上的person引用,然后再加載name引用。這個時候會觸發加載屏障。第二行代碼在屏幕上打印name,不會直接觸發加載屏障,因為不需要加載堆引用——name是局部變量,因此不需要從堆加載引用。不過,System和out,或者println內部可能會觸發其他加載屏障。

\\

這與其他垃圾回收器(例如G1)使用的寫入屏障形成對比。加載屏障的任務是檢查引用的狀態,并在將引用(或者不同的引用)返回給應用程序之前執行一些任務。在ZGC中,它會對加載的引用進行測試,查看是否設置了某些位,具體取決于當前處于哪個階段。如果引用通過測試,就不執行任何其他操作,如果沒有通過,就會在將引用返回給應用程序之前執行一些特定于當前階段的操作。

\\

標記

\\

在了解了這兩項新技術后,現在讓我們來看看ZGC的GC周期。GC周期的第一部分是標記,就是以某種方式查找并標記應用程序可以訪問到的所有堆對象,換句話說,就是查找非垃圾對象。

\\

ZGC的標記分為三個階段。第一階段是STW,在這一階段,GC root被標記為存活。GC root類似于局部變量,應用程序使用它們來訪問堆上的其他對象。從GC root開始遍歷對象圖,如果某些對象無法被訪問到,那么應用程序也就無法訪問到這些對象,它們就被認為是垃圾??梢詮腉C root訪問到的對象集被稱為存活集。GC root標記步驟所需要的時間非常短,因為GC root的總量通常相對較少。

\\

\\

標記階段完成后,應用程序恢復運行,而ZGC將開始下一階段,發遍歷對象圖,并標記所有可訪問的對象。在這一階段,加載屏障會檢查所有已加載的引用,看看它們的掩碼是否已經針對這一階段進行過標記,如果尚未標記,就將其添加到待標記隊列。

\\

在完成這一步后,會出現一個短暫的STW階段,它會處理一些邊緣情況,然后整個標記過程就完成了。

\\

重定位

\\

GC周期的下一個主要部分是重定位。重定位就是要移動存活對象,以便釋放部分堆空間。為什么要移動對象而不是填補空隙?有些GC確實是這樣做的,但這樣會造成不好的后果,即堆分配將變得非常昂貴,因為在分配堆空間時,分配器需要找到放置對象的空閑空間。相反,如果可以釋放大塊內存,堆空間分配就會變得很簡單,只需要將指針按照對象所需的內存量進行遞增就可以了。

\\

ZGC將堆分成頁,在開始進行重定位時,它會選擇一組需要重新定位的存活對象的頁。在選擇好重定位集后,會出現一次STW停頓,ZGC對重定位集中的對象進行重定位,并重新映射它們對新地址的引用。與之前的STW一樣,停頓時間取決于root的數量以及重定位集與存活集的比率,這個比率通常都很小。它不會隨著堆大小的變化而變化,這與其他大部分垃圾回收器一樣。

\\

移動完root之后,下一階段是進行并發重定位。在這個階段,GC線程遍歷重定位集,并重新定位頁中的所有對象。如果應用程序線程嘗試加載重定位集中的對象,但這些對象還未被重定位,那么應用程序線程也可以對它們進行重定位,這是通過加載屏障來實現的,如下面的流程圖所示:

\\

\\

這樣可以確保應用程序看到的所有引用都是最新的,并且應用程序不會對正在被重定位的對象做任何操作。

\\

GC線程最終會重定位重定位集中的所有對象,不過仍然可能存在一些指向這些對象舊地址的引用。GC會遍歷對象圖,并將所有這些引用重新映射到新的地址上,但這是一個非常昂貴的步驟。所以,這一步被并入到下一個標記階段。在標記期間,如果發現未重新映射的引用,則將其重新映射,并標記為存活。

\\

回顧

\\

試圖單獨理解復雜的垃圾回收器(如ZGC)性能特征是很困難的,但有一點是很清楚的,我們在文中所提到的GC停頓都與GC root有關,而與存活對象集、堆大小或垃圾對象沒有關系。標記階段的最后一次停頓是一個例外,它是增量進行的,而且如果超過時間預算,GC將恢復到并發標記,直到下一次進行嘗試。

\\

性能

\\

那么ZGC的性能如何?ZGC的SPECjbb 2015吞吐量數據與Parallel GC(為吞吐量進行過優化)大致相當,平均停頓時間為1毫秒,最長為4毫秒。這與平均停頓時間超過200毫秒的G1和Parallel形成鮮明的對比。

\\

未來的可能性

\\

彩色指針和加載屏障為我們帶來了一些有趣的未來可能性。

\\

多層堆和壓縮

\\

隨著閃存和非易失性內存變得越來越普及,JVM的多層堆將成為可能,在多層堆中,很少被訪問的存活對象將被保存在較慢的內存層中。

\\

我們可以對指針元數據進行擴展,加入一些計數器位,并使用這些位信息來決定是否需要移動對象。在需要使用對象的時候,可以通過加載屏障從相應的內存層獲取對象。

\\

或者也可以不將對象重定位到較慢的內存層,而是將對象保存在主內存中,不過需要對其進行壓縮。在請求對象時,通過加載屏障解對其進行解壓并分配到堆中。

\\

ZGC的狀態

\\

在撰寫本文時,ZGC還處在實驗階段。讀者可以通過Java 11 Early Access版本(http://jdk.java.net/11/)來體驗ZGC,但需要指出的是,要解決一個新垃圾回收器存在的所有問題可能需要很長的一段時間。G1從發布到脫離實驗階段花了至少三年時間。

\\

總結

\\

服務器擁有數百GB甚至是數TB的內存變得越來越普及,Java有效使用內存堆的能力變得越來越重要。ZGC是一個令人興奮的新型垃圾回收器,致力于大幅降低大堆垃圾回收的停頓時間。它通過使用彩色指針和加載屏障來實現這一點,它們都是Hotspot新引入的GC技術,并帶來了一些有趣的未來可能性。ZGC將作為Java 11的實驗性垃圾回收器,讀者現在可以通過Java 11 Early Access體驗ZGC。

\\

英文原文:https://www.opsian.com/blog/javas-new-zgc-is-very-exciting/

總結

以上是生活随笔為你收集整理的Oracle即将发布的全新Java垃圾收集器 ZGC的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。