天天看點

垃圾收集器與記憶體配置設定政策——記憶體配置設定政策與回收政策

記憶體配置設定政策與回收政策

參考:《深入了解Java虛拟機》-jvm進階特性與最佳實作(周志明著)

前言

Java技術體系所倡導的記憶體管理最終可以貴大為自動化解決兩個問題:給對象配置設定記憶體以及回收配置設定給對象的記憶體。

如下的内容是基于Client模式下預設的垃圾收集器組合

一、記憶體配置設定的普遍規則

1、對象優先在Eden空間配置設定,大多情況下,對象在新生代的Eden空間進行配置設定,當Eden空間沒有足夠的記憶體時,将觸發一次Minor GC,可以通過設定-XX:+PrintGCDetails 這個收集器日志參數,高速虛拟機在發生垃圾回收的時候列印GC日志。

注意:

Minor GC 和 Full GC 有什麼不一樣嗎?

新生代GC(Minor GC):是指新生代的垃圾收集動作,因為Java對象大多朝生夕滅,是以Minor GC發生的非常頻繁。一般回收速度也比較快。

老年代GC(Major GC / Full GC):Major GC清理Tenured區,用于回收老年代,出現Major GC通常會出現至少一次Minor GC。

Full GC是針對整個新生代、老生代、元空間(metaspace,java8以上版本取代perm gen)的全局範圍的GC。Full GC不等于Major GC,也不等于Minor GC+Major GC,發生Full GC需要看使用了什麼垃圾收集器組合,才能解釋是什麼樣的垃圾回收。

2、大對象直接進入老年代,最典型的大對象就算是指那種很長的字元串以及數組。虛拟機提供了-XX:PretenureSizeThreshold 參數,令大于這個設定值的對象直接在老年代配置設定。這樣做的目的是避免在Eden空間以及兩個Survivor區之間發生大量的 記憶體複制。

需要注意的是,-XX:PretenureSizeThreshold 這個參數對Parallel Scavenge 收集器不起作用,如果遇到必須使用該設定的場合,可以考慮使用ParNew 加 CMS 收集器組合

3、長期存活的對象将進入老年代

虛拟機給每個對象都定義了一個年齡計數器,如果對象在Eden出生,并經過第一次Minor GC 後存活,并且被Survivor容納的話,将被移動到Survivor空間中,并且對象年齡設定為1,對象在Survivor區中每熬過一次Minor GC,年齡就增加1歲,當它的年齡增加超過預設(15歲)的時候,會被晉升到老年代中,對象晉升老年代的年齡門檻值,可以通過設定參數 -XX:MaxTenuringThreshold設定

4、動态對象年齡判斷

為了更好地适應不同程式的記憶體情況,虛拟機并不是永遠地要求對象的年齡必須達到MaxTenuringThreshold 才能晉升老年代。如果再Survivor空間中相同年齡的所有對象大小的總和超過了Survivor空間的一半,年齡大于等于該年齡的對象就可以直接進入到老年代。

5、空間配置設定擔保

在發生Minor GC之前,虛拟機會先檢查老年代最大可用的連續空間是否大于新生代所有對象的總和。如果這個條件成立,那麼Minor GC 可以確定實施安全的。如果不成立,則虛拟機會檢視HandlerPromotionFailure設定是否允許擔保失敗。如果允許,那麼就會繼續檢查老年代最大可用的連續空間是否大于曆次晉升到老年代對象的平均大小,如果大于,将嘗試一次Minor GC,盡管這次Minor GC 是有風險的。如果小于或者HandlerPromotionFailure設定的值不允許冒險,那這時也要改為進行一次Full GC

繼續閱讀