GC,即java垃圾回收機制。要準確理解GC,咱們能夠從 「GC的觸發」、「回收的對象」以及「作了什麼」這三個方面進行法分析。java
GC分爲Minor GC與Full GC。其中,Minor是針對於新生代的回收,Full GC針對於老年代的回收。算法
java的內存分配是分代分配的,java堆的內存分爲新生代與老年代。在新生代中,內存區域又分爲一個Eden區域與兩個Survivor區域。安全
GC觸發的條件分爲:線程
(1)程序調用System.gc。對象
(2)系統自身決定。隊列
系統判斷是否執行GC:通常狀況下,由於對象都是分配在Eden區域中,因此當Eden區域沒有足夠的空間的時候,將會發起一次Minor GC ;對於Full gc的觸發條件是:當老年代沒有足夠的空間的時候,就會進行一次Full GC。內存
上面只是通常狀況,在實際的運行過程當中,還須要考慮一個空間分配擔當的問題:虛擬機
在發生Minor GC 以前,虛擬機會首先檢查老年代最大可用的連續空間是否大於新生代的對象總空間,若是這個條件成立,那麼Minor GC能夠確保是安全的,Minor GC能夠進行。若是這個條件不成立,虛擬機則會查看 HandlePromotionFailure 設置值是否容許擔當失敗。若是容許,那麼會繼續檢查老年代的最大可用空間是否大於歷次晉升到老年代對象的平均大小。若是大於,則嘗試着進行一次Minor GC,儘管此次GC是有風險的;若是小於,或者HandlePromotionFailure設置值爲不容許,則要進行一次Full GC。io
判斷哪些對象須要被回收,主要是依據可達性分析算法。該算法就是經過一系列的稱爲「GC Roots」的對象做爲起點,從這些節點向下搜索,搜索走過的路徑稱爲引用鏈,當一個對象到GC Roots沒有任何的引用鏈的時候,則證實還對象是不可達的。垃圾回收
即便在可達性分析中不可達對象也並不是是必定要回收的。宣告一個對象的死亡回收須要通過兩個步驟。第一步,若在可達性分析事後發現了沒有與「GC Roots」有引用鏈的對象,則將它進行第一次標記而且進行一次篩選,篩選的條件爲是否有必要執行finalize()方法。 第二步,若被斷定爲有必要執行finalize()方法(有必要執行是指該對象覆蓋了finalize()方法而且沒有被執行過), 則會放入F-Queue隊列,並自動建立一個低優先級的finalize線程來執行釋放操做。若是在一個對象釋放前被其餘對象引用,則該對象會被移除F-Queue隊列。
主要作了清理對象,整理內存的工做。當GC線程啓動時,會經過可達性分析法把Eden區和From Space區的存活對象複製到To Space區,而後把Eden Space和From Space區的對象釋放掉。當GC輪訓掃描To Space區必定次數後,把依然存活的對象複製到老年代,而後釋放To Space區的對象。