JVM知識點掃盲系列(1)

JVM知識點掃盲系列(1)

每次young gc的時間,和eden空間的大小是正比關係嗎?

那young gc的時間到底和哪些因素有關呢?

來看一段代碼,邏輯很簡單,不斷的分配1M的大小,直到觸發YGC。

// -Xmx2g -Xms2g -Xmn500m -XX:+PrintGCDetails 
// -XX:+UseConcMarkSweepGC -XX:+PrintHeapAtGC
public class GcCase {
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
allocate_1M();
}
}
public static void allocate_1M() {
byte[] _1M = new byte[1024 * 1000];
}
}
JVM知識點掃盲系列(1)

這裡設置了新生代的大小是500m,按照8:1:1的比例,eden的大小應該是400m。我們可以大概梳理一下:

1、每次分配1M,分配到第400次時,eden被1M的內存塊塞滿了

2、為了能夠塞下後面的數據的,只能觸發一次YGC

3、執行YGC之前,必須等所有的業務線程全部掛起,這個點就是所謂的安全點(safepoint),從這一刻開始,JVM是凍結的,只有虛擬機線程才能執行,也是從這一刻開始計時。

一次YGC過程包括下面幾個步驟,每個步驟的耗時,也就是整個YGC的耗時。

1、找出所有可能存活的對象,一個也不能少,這是標記過程的耗時。

從GC Roots開始,遍歷對象,所有能遍歷到的對象都是算是存活對象,打上一個標記。正常情況下,需要的關心的GC Roots包括下面幾個:類的靜態引用、業務線程進入安全點時,正在執行方法中的引用類型變量(包含參數)、部分老年代的對象(持有引用執行新生代對象),還有其它不需要太關注的,比如VM內部的數據結構。

2、存活對象被標記出來之後,需要把這些對象從eden區或者from區,複製到to區,這個複製過程的耗時,和存活對象的大小數量有很大的關係。這是複製過程的耗時。

3、如果開啟了GC日誌 -XX:+PrintGCDetails,那麼在YGC過程中,還會記錄一些數據到日誌中,這個日誌的寫入過程,也有可能被影響,這段時間也是YGC的耗時。

所以,young gc的時間,和eden空間的大小是正比關係嗎?

答案是沒有多大關係。

JVM知識點掃盲系列(1)


分享到:


相關文章: