擴容新生代為什麼能夠提高GC的效率

xbhog 發表於 2022-01-26

擴容新生代為什麼能夠提高GC的效率

該文章預設讀者對JVM的基礎有所瞭解

在學習JVM的時候,遇到了個人感覺比較有意思的問題,通過視訊學習整理了一下。

先來上圖:

image-20220125151642305

大部分情況下,物件都會進入Eden區進行分配,當該空間滿了以後,進行輕GC,如果物件存活,則會進入s0或者s1。

擴充套件:如何判斷物件存活

採用根可達性分析演算法來判斷

可作為根的物件有:

  1. 虛擬機器棧中引用的物件
  2. 本地方法棧中引用的物件
  3. 方法區中類靜態屬性引用的物件
  4. 方法區常量引用的物件

GC的耗時由兩部分組成:

  1. 掃描整個新生代所要花費的時間
  2. 將存活物件複製到倖存區的時間

所以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的間隔,從而儘可能的使得物件變為垃圾,來減少記憶體的移動。