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