垃圾回收(Garbage Collection),採用分代收集算法思想,頻繁收集年輕代,較少收集老年代,基本不動永久代。
按照回收區域又分爲兩種類型,一種只針對年輕代的Minor Gc,另一種針對老年代偶爾伴隨着新生代的Major Gc。
垃圾指內存中不再使用的空間,如沒有任何棧引用對象指向的堆內存空間。
垃圾分類:
⑴ 強引用(StrongReference)【不是垃圾】:常見的普通對象引用,就算出現了OOM也不會對該對象進行回收
。
⑵ 軟引用(SoftReference)【可能是垃圾】:需要SoftReference類實現,內存空間不足了,垃圾回收器就會回收它
。
⑶ 弱引用(WeakReference)【垃圾】:需要WeakReference類實現,只要GC,對象就被回收
。
⑷ 虛引用(PhantomReference):虛引用主要用來跟蹤對象被垃圾回收器回收的活動
。
⑴ 引用計數法:存在“循環依賴”問題,棄用
;
⑵ 枚舉根節點做可達性分析法:通過一些被稱爲垃圾回收根(GC Roots)的對象作爲起點,從這些節點開始向下搜索,搜索走過的路徑被稱爲引用鏈(Reference Chain),當一個對象到 GC Roots 沒有任何引用鏈相連時(即從 GC Roots 節點到該節點不可達),則證明該對象是不可用的
;
GC Root:是一組必須活躍的引用
。
可作爲 GC Root 的對象包括以下4種:
① 棧(棧幀中的本地變量表)中引用的對象
;
② 方法區中類靜態屬性引用的對象
;
③ 方法區中常量引用的對象
;
④ 本地方法棧中 JNI(即一般說的 Native 方法)引用的對象
;
Minor GC: Eden區滿了或者新創建的對象大小大於Eden所剩空間;
Major GC: 老年代空間不足、永久代空間不足、minor gc時出現promotion failure、顯示調用System.gc();
註釋:
promotion failure,是在minor gc過程中,survivor的剩餘空間不足以容納eden及當前在用survivor區間存活對象,只能將容納不下的對象移到年老代(promotion),而此時年老代滿了無法容納更多對象,通常伴隨full gc,因而導致的promotion failure。這種情況通常需要增加年輕代大小,儘量讓新生對象在年輕代的時候儘量清理掉。
複製算法(Minor GC使用的算法):
從GC Root開始,通過Tracing 從Eden 和 From區找到存活對象,拷貝到To區。GC完成後,From、To交換身份,下次內存分配從To區開始。存活的對象每經歷一次Minor GC ,年齡會加1,當達到某個閥值(默認15,可通過-XX:MaxTenuringThreadshold配置)就會成爲老年代對象。
標記-清除(Major GC使用的算法):
當堆中有效空間被耗盡,會暫停整個程序(stop the world)進行標記和清除。
標記:從GC Root開始掃描,標記存活的對象(GC Root可達對象);
清除:遍歷整個堆,清除未被標記的對象;
標記-壓縮(Major GC使用的算法):
標記:從GC Root開始掃描,標記存活的對象(GC Root可達對象);
壓縮:遍歷整個堆,將標記的對象往一端移動,直接清除邊界以外的內存;
標記-清除-壓縮(Major GC使用的算法):
- Mark-Swap 和 Mark-Compact的結合;
- 和Mark-Swap 一致,當進行多次GC後才Compect;
小總結:
年輕代Minor GC使用複製算法;
老年代Major GC使用標記-清除 和 標記-清除-壓縮算法;
內存效率: 複製算法 > 標記清除 > 標記壓縮;
內存整齊度:複製算法 = 標記壓縮 > 標記清除;
內存利用率:標記清除 = 標記壓縮 > 複製算法;