2014-01-31 29 views
6

在大多數在線教程中,我們可以看到他們顯示GC中有兩個倖存者空間。 當我們實際上只有一個倖存者空間時,需要什麼? 有兩個倖存者空間對性能有什麼影響?Java GC:爲什麼使用兩個倖存者空間

+0

這可能會幫助你。 http://stackoverflow.com/questions/10695298/java-gc-why-two-survivor-regions – Grmpfhmbl

回答

19

原因是,你猜對了,表現。首先讓我解釋爲什麼存在這些倖存空間。有兩種主要的垃圾收集器的設計相對於對象搬遷的基本關注:

  • 就地密實集電極;

  • a 複製收集器。

複製收集器的操作速度更快,並且可以高效並行化,基本上是因爲它不會覆蓋任何對象。如果不在每次GC運行之後使用一個「活動」和一個「休眠」堆空間,這兩個交換角色就無法實現這一點。

複製收集

注意的基本設計:接下來是 HotSpot的實際GC的描述,而這是當初設計的一部分,在1970年ACM文件中提出它的那些方面由CJ切尼。 HotSpot增加了進一步的改進,其中之一是增加了伊甸園空間下面解釋。

當複製收集程序啓動時,有兩個空間涉及:

  • 空間:存儲器分割的連續塊分爲兩個區域:從最後的GC
    • 倖存者;
    • 新對象(自上次GC創建以來);
  • 空間:完全空白。

GC運行的任務是確定在所有存活的對象從空間,並將其複製到空間。

由於空間正在被建立起來,在空間將被完全疏散,沒有什麼需要寫入。

複製GC是單程

的複製收集的主要優點是,它是單通:我們只是掃描所有的GC根,複製所有這些對象,然後掃描進一步的那些對象參考,複製所有參照物。我們從不重新訪問任何對象,也不需要任何支持內存結構。 (請看 here對此有一個很好的解釋)。

正向指針

由於每個存活的對象被重新定位,舊的位置可以打上一個轉發指針,然後可以有效地使用該信息作爲倖存對象被掃描到重新定位的對象的引用,並更新了這些引用。舊的參考指向前向指針,所以新的指針值只是一個查找。

爲什麼第三個空間?

你的問題,「爲什麼有兩個倖存者空間?」實際上會更好地措辭,「爲什麼一個單獨的伊甸園空間?」。

HotSpot已經引入了Eden空間作爲一個優化,保持新分配區域的容量不變,押注大部分對象立即變成垃圾的結果。你可以看看Eden作爲內存的一部分共享在兩個空間之間—這部分可能會在下一個GC上被釋放。這實際上提高了內存利用率

+0

報價:「然後掃描這些對象的進一步參考,複製所有的指示。」我不太理解這條線。例如,如果兩個對象互相引用,那麼上述過程可能永遠不會結束?或者更糟的是,導致重複/無限的對象。他們如何處理這個問題? – du369

+1

轉發指針將對象標記爲已移動。 –

+0

@ du369這是一個簡單的無限循環預防,您只需將該對象標記爲已處理(或正在進行)並且不再處理它。 – maaartinus

相關問題