JVM----觸發YoungGC與FullGC示例與思路

之前接觸到的一道題目:請寫一段程序,讓其運行時的表現爲觸發5次ygc,然後3次fgc,然後3次ygc,然後1次fgc,請給出代碼以及啓動參數。

找到了阿里中間件團隊博客裏面的兩篇文章:

  • GC悲觀策略之Parallel GC篇
  • GC悲觀策略之Serial GC篇
  • 文章中總結的最重要的規則如下:

    總結上面分析的策略,可以看到採用Parallel GC的情況下,當YGC觸發時,會有兩個檢查:
    1、在YGC執行前,min(目前新生代已使用的大小,之前平均晉升到old的大小中的較小值) > 舊生代剩餘空間大小 ? 不執行YGC,直接執行Full GC : 執行YGC;
    2、在YGC執行後,平均晉升到old的大小 > 舊生代剩餘空間大小 ? 觸發Full GC : 什麼都不做。

    在寫代碼的時候,先嚐試了直接new一個大對象,但直接這麼做會在Full GC之前觸發一次Young GC,測試下來加了 -XX:-ScavengeBeforeFullGC 也還是會先Young GC (Full GC (Allocation Failure)之前)。

    因此還是需要逐步地增加內存佔用,並有目的地刪除一部分引用,通過上述的兩個規則來觸發Full GC和Young GC。

    最終的啓動參數如下:

    -Xms41m -Xmx41m -Xmn10m -XX:+UseParallelGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
    

    代碼如下:

    package com.spirit.test;
    import java.util.ArrayList;
    import java.util.List;
    /**
     * @author Spirit
     * @since 2019-02-28
     */
    public class GcTest {
        private static final int _1MB = 1024 * 1024;
        public static void main(String[] args) {
            System.out.println("0.---");
            List caches = new ArrayList();
            for (int i = 0; i < 11; i++){
                caches.add(new byte[3 * _1MB]);
            }
            System.out.println("1.---");
            caches.add(new byte[3 * _1MB]);
            caches.remove(0);
            caches.add(new byte[3 * _1MB]);
            for (int i = 0; i < 8; i++) {
                caches.remove(0);
            }
            caches.add(new byte[3 * _1MB]);
            System.out.println("2.---");
            for (int i = 0; i < 7; i++){
                caches.add(new byte[3 * _1MB]);
            }
        }
    }
    
    發表評論
    所有評論
    還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
    相關文章