JAVA虛擬機學習總結——垃圾收集與內存回收

垃圾收集器與內存回收策略

判斷對象是否已死

  • 引用計數器
  • 可達性分析算法

四種引用類型

  • 強引用:只要這類引用還存在,就不會回收。
  • 軟引用:在系統將要發生內存溢出異常之前,將會把這些對象列進回收範圍之中進行二次回收。
  • 弱引用:只能生存到下一次垃圾收集發生之前。當垃圾收集工作時,無論當前內存是否足夠,都會回收掉只被弱引用關聯的對象。
  • 虛引用:一個對象是否有虛引用存在,完全不會對其生存時間構成影響,也無法通過虛引用來取得一個對象實例。爲對象設置虛引用的唯一目的就是能在這個對象被垃圾回收時收到一個系統通知。

關於可達性分析

在可達性分析算法中,對於不可達的對象,要經歷兩個標記過程:
+ GC Roots不可達,第一次標記。
+ 進行一次關於finalize()的篩選,如果對象沒有覆蓋finalize()或者finalize()已經被調用過,finalize()沒有 必要執行。對象可以覆寫finalize()方法,實現自救,但是隻能自救一次,因爲每個對象的finalize方法只會被調用一次。

無用的類

判斷一個類是否是“無用的類”:
+ 該類的所有實例都已經被回收。
+ 加載該類的ClassLoader 已經被回收(是否可以用軟引用或弱引用實現)。
+ 該類的Class對象沒有在任何地方被引用,無法在任何地方通過反射訪問該類的方法

垃圾回收算法

  • 標記清除。
  • 複製算法。比較適合新生代。
  • 標記整理算法。比較適合老年代。

垃圾收集器

新生代

Serial收集器

單線程的垃圾收集器,在它進行工作時,必須暫停其他所有的工作線程,直到它收集結束。因爲沒有線程交互的開悄,所以簡單高效。

ParNew收集器

就是Serial收集器的多線程版本。

Parallel scavenge收集器

爲了達到一個可控制的吞吐量。吞吐量=用戶代碼運行時間/(用戶代碼運行時間+垃圾收集時間)

老年代

Serial Old收集器

Serial 的老年代版本

Parallel old收集器

Parallel Scavenge的老年代版本

CMS收集器

獲取最短回收停頓時間的收集器
初始標記,併發標記,重新標記,併發清除

綜合

G1收集器

內存分配策略

  • 對象優先在Eden區中分配
  • 大對象直接進入老年代,如很長的字符串和數組,以避免在Eden區和兩個Survivor區之間發生大量的內存複製。
  • 長期存活的對象將進入老年代。對象在Survivor區每經過一次MinorGC,年齡就增加一歲,當它的年齡增加到一定程度,就會被晉升到老年代。
  • 動態對象年齡的判定。如果在Survivor空間中相同年齡的所有對象大小總和大於Survivor空間的一半,年齡大於或等於該年齡的對象提前進入老年代。
  • 空間分配擔保。在發生MinorGC之前,虛擬機會首先檢查老年代最大可用的連續空間是否大於新生代所有對象總空間,如果大於,那麼MinorGC可以確保是安全的,如果不成立,則虛擬機會查看是否允許擔保失敗,如果允許,那麼會繼續檢在老年代最大可用的連續空間是否大於歷次晉升到老年代對像的平均大小,如果大於,將嘗試者進行一次MinorGC,儘管這次MinorGC是有風險的:如果小於,或者不允許冒險,那這時會改爲進行一次FullGC。

MinorGC與Major GC/Full GC

MinorGC:發生在新生代的垃圾收集動作,頻繁,動作也快。當新生代Eden區滿時,就會觸發。
Major GC/Full GC:發生在老年代,一般也會同時觸發MinorGC。MajorGC速度比較慢。當老年代滿時會觸發,同時回收新生代和老年代。當水久代滿時也會觸發FulIGC,會導致Class, Method 元信息卸載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章