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

擴容新生代為什麼能夠提高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的間隔,從而儘可能的使得對象變為垃圾,來減少記憶體的移動。