2016-10-21 52 views
5

我想更深入地瞭解Java的垃圾回收。Java垃圾收集器總是需要「停止世界」嗎?

在HotSpot JVM世代收集中,堆中有三個區域(年輕一代,舊一代和永久代)。此外,還有兩種算法:

1)Mark Sweep Compact

2)併發標記和清除

GC是否需要「Stop-the-world」取決於所使用的算法而不是其運行的算法?換句話說,如果我在所有三個區域使用1)作爲GC算法,STW將總是會發生?

另外,我明白不同的是第二個GC算法不需要壓縮,最終會導致碎片化。所以第二個問題是爲什麼壓縮需要STW暫停?

回答

7

壓縮導致STW暫停的關鍵原因如下,JVM需要移動對象並更新對它的引用。現在如果在更新引用和運行訪問它的舊引用的應用程序之前移動對象,則會出現問題。如果先更新引用並嘗試移動對象,則更新後的引用是錯誤的,直到對象移動並且對象未移動時的任何訪問都會導致問題。

對於CMS和並行收集器,年輕一代的收集算法都是類似的,它停止了世界,即在收集時應用程序停止 JVM正在做的事情是,標記所有可從根集訪問的對象,將對象從伊甸園裏的倖存者空間和活動物品,這些物品在老一代的存在門檻之後仍然存在。當然,JVM必須更新所有已移動對象的引用。

對於舊一代並行採集器在單步停止世界(STW)階段執行所有標記,壓縮和引用更新,這會導致GB中的堆停頓在幾秒鐘內。這對於具有嚴格響應時間要求的應用程序來說是痛苦的。迄今爲止,Paralle收集器仍然是用於吞吐量或批處理的最佳收集器(在Oracle Java中)。事實上,即使停留時間比並行收集器花費的時間多於CMS,我們仍然看到了相同的情況,但我們仍然獲得了更高的吞吐量,這與壓縮導致的空間局部性更好有關。

CMS通過同時做標記解決了主要收藏中高停頓的問題。有2個STW部分,初始標記(從根集合獲取參考)和備註暫停(標記結束時的小STW暫停,用於處理標記和應用程序同時工作時對象圖的變化)。對於幾GB的堆大小和合理的應用程序線程數,這兩個暫停都在100-200毫秒的範圍內(記住更多活動線程更多根)

G1GC計劃成爲CMS的替代品並接受暫停目標。通過增量壓縮堆來保持碎片。雖然工作是增量式的,所以你可以得到較小的暫停,但這可能以更頻繁的暫停爲代價

以上都不是緊湊堆(CMS根本不緊湊),而應用程序正在運行。 AZUL GPGC垃圾收集甚至可以在不停止應用程序的情況下進行壓縮並處理參考更新。因此,如果您想深入瞭解GC如何工作,則需要閱讀GPGC的算法。 AZUL把它當作一個暫停收藏者來銷售。

+2

**神奇**關於地理信息系統常常令人迷惑的複雜性的總結,我認爲我以前沒有閱讀過如此簡潔而精確的地理信息系統的描述。要添加的另一個GC是[Shenandoah](http://openjdk.java.net/projects/shenandoah/),它是爲Java 9構建的,但有一個用於Java 8的backport。吞吐量不如G1,但如果你的目標是超低的停頓,它正在推動極限。 https://rkennke.wordpress.com/2016/02/08/shenandoah-performance/ – michaelok

+0

謝謝Michaelok – Deven

0

無論您選擇哪種GC算法,都會出現停止世界。停止這個世界意味着JVM正在阻止應用程序運行以執行GC。當停止世界發生時,GC之外的每個線程將停止執行任務。

+0

你知道,有增量和併發垃圾收集算法。 –

+0

是增量GC也停止應用程序線程。請看看http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html#icms –

+0

Azul Systems有一個GC算法,它是Zing虛擬機不會停止世界,但我認爲OP是在談論Oracle虛擬機,而那些虛擬機會回落到STW,儘管當然,GC算法已經發展多年並不斷變得更好,看一看在Shenandoah「Shenandoah是一個超低暫停時間的垃圾收集器,通過與正在運行的Java程序同時執行更多的垃圾收集工作來減少GC暫停時間。」http://openjdk.java.net/projects/shenandoah/ – michaelok

6

openjdk中所有免費提供的GC都有一些停止世界事件。而不僅僅是GC,其他的東西如去最優化也可以觸發安全點。

但並非所有的暫停都是平等的。 CMS和G1不需要使用老一代的實時數據集來縮放暫停時間,因爲它們只是在暫停期間掃描一部分對象並同時完成大部分工作,這與串行和吞吐量收集器不同。

有些工作正在進行引進another collector這將進一步從實時數據集大小分離的暫停時間。

另外其他GC實現存在這避免全局暫停 - 它們仍可能會遇到的每線程的暫停 - 或使暫停持續時間O(1),即,獨立的實時數據集的大小。通常引用的例子是azul's C4 collector

所以第二個問題是爲什麼壓縮需要STW暫停?

壓實裝置移動的物體。移動對象意味着指針需要更新。當應用程序線程仍在運行時,實現安全性非常困難或昂貴。

併發算法通常會在吞吐量和複雜度方面付出一定代價,以換取其較低的暫停時間。不進行壓縮使CMS對於併發採集器相對簡單(!)。