- 概述
- 判斷對象存亡
- 垃圾收集算法
- 垃圾收集器
GC目前高度自動化,but當GC成為系統高并發瓶頸時,就需要對GC進行必要的監控和調節。針對JVM,GC主要針對**堆**。通過**垃圾收集器**,按照**垃圾收集算法**,對記憶體進行配置設定和回收。
- **引用計數法reference counting**
有引用,計數器加1,引用失效,計數器減1,計數器為0的對象不再被使用的。但是難以解決Java中的互相循環引用問題。
- **根搜尋算法GC root tracing**
以GC Root為根節點,向下搜尋,無引用鍊的對象,證明不可用。
可作為GC Root的對象有:
- 虛拟機棧引用對象
- 方法區中類靜态屬性引用對象
- 方法區常量引用對象
- JNI引用對象
-
引用
傳統定義:如果引用類型存儲的數值代表另一塊記憶體的起始位址,就稱這塊記憶體代表一個引用。
JDK1.2以後,引用進行了劃分:
- 強引用,普遍存在
- 軟引用,記憶體溢出之前,進行回收,仍然溢出,抛出異常,參照SoftReference
- 弱引用,下一次GC之前存活,WeakReference
- 虛引用,主要是獲得GC通知,不影響生存周期。
-
對象緩刑
第一次标記,GC Root标記的不可用對象,并且判斷對象是否覆寫finalize()或finalize()方法已被JVM調用過。如果是,标記為沒有必要執行。
第二次标記,如果判定為有必要執行,則将此對象放到一個F-Queue中,JVM自動啟動一個低優先級線程處理。為了防止死循環或執行緩慢等意外情況,GC還會對F-Queue中對象進行第二次小規模标記。如果對象仍然沒有重新與引用鍊上建立關聯,則GC掉。
-
回收方法區
成本效益比堆低很多。主要回收“廢棄常量”,對于hotspot虛拟機,提供了參數進行配置,尤其是大量使用反射,動态代理,CGLib等bytecode架構時,都需要JVM具備類解除安裝功能,保證永久代不會溢出。判斷“廢棄常量”需滿足:
- 該類所有執行個體被回收
- 加載該類的classloader被回收
- 該類對象的java.lang.class對象沒有任何引用,防止反射
- 标記-清除算法Mark-Sweep
标記待清除對象,參照上節**對象緩刑**,清除對象,缺點較明顯:
- 效率低
- 容易産生大量不連續記憶體碎片,當程式需要配置設定大對象時并無足夠連續記憶體時,提前觸發下次GC
-
複制算法Coping
- 記憶體分兩塊,一塊用完時将存活對象複制到另一塊,并清理目前塊。JVM都采用這種算法回收新生代。
- 98%對象朝生夕死,HotSpot虛拟機将記憶體分為一塊Eden(80%),兩塊Survivor(20%),每次使用Eden和其中一塊survivor。回首時,将存放對象放到另一塊survivor上。當多餘10%記憶體對象存活時,依賴老年代記憶體,進行配置設定擔保。
-
标記-整理算法
複制算法,對象存活率較高時,需要執行較多的複制操作,效率較低。标記整理算法,是标記出存活對象,GC時,讓存活對象向記憶體一端移動,然後直接清理掉端邊界以外記憶體。
-
分代收集算法
目前商業JVM都采用分代收集,把Java堆分為新生代和老年代。新生代中,存活對象少,采用複制算法。老年代對象存活率高,沒有額外空間進行配置設定擔保,必須使用“标記-清理”或“标記-整理”算法進行回收。
> 根據收集算法,有多種收集器的實作,沒有最好,隻有最合适
-
Serial收集器
單線程,暫停其它工作線程,依然是JVM運作在Client模式的預設收集器,簡單而高效。在使用者桌面應用場景中,收集幾十甚至上百M的新生代,停頓時間會控制在100毫秒以内,可接受。
-
ParNew收集器
Serial收集器的多線程版本,單核效果比Serial低。
-
Parallel Scavenge收集器
新生代收集器,複制算法,“吞吐量優先”,可配置停頓時間和吞吐量大小,可打開GC自适應調節政策,自動調節新生代,Eden與Subvivor區比例。
-
Serial Old收集器
是Serial收集器的老年代版本,單線程,“标記-整理”算法
-
Parallel Old收集器
多線程,“标記-整理”,注重吞吐量及CPU資源敏感的場合,優先考慮Parallel Scavenge收集器加Parallel Old收集器
-
CMS收集器
Concurrent Mark Sweep,最短回收停頓時間,重視響應速度,“标記-清除”,分4部:
- 初始标記
- 并發标記
- 重新标記
- 并發清除
其中,初始和重新标記,單線程,缺點:
- CPU資源敏感
- 無法處理浮動垃圾
- 标記清除算法,清理不及時,觸發Full GC
-
G1收集器
Garbage First,“标記-整理”,收集毫秒級,将整個Java堆分隊多個region,維護一個優先清單,最大限度提升收集效率
I am a slow walker, but I never walk backwards.