Java 分代回收

1、YGC做了哪些操作

Eden區:
1)對象回收
2)存活對象 被復制到 Survivor區的"To"(age不加1)
Survivor的From:
(3)對象回收
存活對象
4)不滿足年齡條件的被復制到 Survivor區的“To”(age加1)
5)滿足年齡條件的移入年老代

2、GC中的一些點

1、Minor GC會一直重復這樣的過程,直到"To"區被填滿,會將所有對象移動到年老代中。
2、動態判斷對象的年齡。如果Survivor區中相同年齡的所有對象大小的總和大于Survivor空間的一半,
年齡大于或等于該年齡的對象可以直接進入老年代。
3、空間分配擔保。每次進行Minor GC時,JVM會計算Survivor區移至老年區的對象的平均大小,
如果這個值大于老年區的剩余值大小則進行一次Full GC,如果小于檢查HandlePromotionFailure設置,
如果true則只進行Monitor GC,如果false則進行Full GC。
4、當使用G1,CMS 時,FullGC發生的時候 是 Serial+SerialOld。
當使用ParalOld時,FullGC發生的時候是 ParallNew +ParallOld.

3、JVM參數

-XX:NewSize 設置年輕代的初始大小
-XX:MaxNewSise 設置年輕代的最大值
建議設為整個堆大小的1/3或者1/4,兩個值設為一樣大。

-XX:SurvivorRatio
設置Eden和其中一個Survivor的比值,默認是8比1。

-Xmx 堆的最大值;
-Xms 堆的最小值;
兩個值最好設置為相等。

-XX:+PrintTenuringDistribution
用于顯示每次Minor GC時Survivor區中各個年齡段的對象的大小。

-XX:MaxTenuringThreshold和-XX:InitialTenuringThreshold
用于設置Survivor區對象晉升年老代中年齡的最小值和最大值

-XX:NewRatio=1
修改新生代和老年代之間的內存比例;

4、1.6、1.7、1.8關于永久代的變化

移除永久代的工作從JDK1.7就開始了。JDK1.7中,存儲在永久代的部分數據就已經轉移到了Java Heap或者是 Native Heap。
但永久代仍存在于JDK1.7中,并沒完全移除,譬如符號引用(Symbols)轉移到了native heap;
字面量(interned strings)轉移到了java heap;類的靜態變量(class statics)轉移到了java heap。

static String base = "string";
public static void main(String[] args) {
    List list = new ArrayList();
    for (int i=0;i< Integer.MAX_VALUE;i++){
        String str = base + base;
        base = str;
        list.add(str.intern());
    }
}
JDK 1.6 的運行結果:PG SPACE
JDK 1.7 的運行結果:java.lang.OutOfMemoryError: Java heap space 
JDK 1.8 的運行結果:java.lang.OutOfMemoryError: Java heap space

可以大致驗證 JDK 1.7 和 1.8 將字符串常量由永久代轉移到堆中。

5、Metaspace(元空間)

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容