擴容新生代為什麼能夠提高GC的效率
該文章預設讀者對JVM的基礎有所瞭解
在學習JVM的時候,遇到了個人感覺比較有意思的問題,通過視訊學習整理了一下。
先來上圖:
大部分情況下,物件都會進入Eden區進行分配,當該空間滿了以後,進行輕GC,如果物件存活,則會進入s0或者s1。
擴充套件:如何判斷物件存活
採用根可達性分析演算法來判斷
可作為根的物件有:
- 虛擬機器棧中引用的物件
- 本地方法棧中引用的物件
- 方法區中類靜態屬性引用的物件
- 方法區常量引用的物件
GC的耗時由兩部分組成:
- 掃描整個新生代所要花費的時間
- 將存活物件複製到倖存區的時間
所以CG耗時=T1+T2;
假設:
新生代空間 (Space1): 200m,每隔5s GC一次,每次GC耗時100ms
GC=T1+T2=100ms
擴容新生代空間(Space2)(兩倍): 400m,每隔10s GC一次,每次GC耗時200ms
GC=2*(T1+T2) =200ms ?(對不對)
其中我們需要考慮物件A的存活時間,它會影響到T2時間。
假設物件A存活時間:7S;
在Space1中 GC的時候物件A是存活的,那麼就需要對物件進行移動,所以Space1中的GC=T1+T2。
在Space2中GC的時候物件A變為垃圾,那麼就不需要對垃圾進行移動,所以在Space2中的GC=2*T1;
在垃圾回收演算法中,JVM中移動記憶體物件的耗時比掃描(演算法有優化)整個新生代的耗時是遠遠高於的。(前提條件)
由此可以得出,擴大新生代確實能夠提高GC的效率,其中起決定的因素不是空間的大小,而是存活物件的大小;
增加整個空間的大小,可以拉長GC的間隔,從而儘可能的使得物件變為垃圾,來減少記憶體的移動。