引用計數演算法
給物件加一個計數器,引用一次+1,引用時效就-1,當計數器=0時物件就不能再被使用;
實現簡單,判定效率高;Java虛擬接沒有使用,主要原因是很難解決物件之間迴圈引用問題;
GC演算法:
GC Roots 作為起始點,開始向下搜尋,這個搜尋路徑叫做引用鏈,當一個物件到GC Roots沒有任何引用鏈,那麼這個物件就是不可用的。
Java中可作為GC Roots的物件:虛擬機器棧中的引用物件、方法區中類靜態屬性引用物件、方法區中常量引用物件等。
標記清除演算法
分為標記和清除階段,首先標記所有需要回收的物件,在標記完後統一回收標記的物件。
堆中的老年代:因為存活率高,沒有額外空間進行分配擔保,就必須使用標記清理演算法回收。
標記清理演算法問題:
- 1、標記和清除的效率不高;
- 2、標記清除後會產生大量不連續的記憶體碎片,當需要分配較大物件時無法找到足夠記憶體,又會觸發垃圾收集動作;
複製演算法
堆中的新生代:每次垃圾回收都有大量物件死去,只有少量存活所以使用複製演算法;
jvm的複製演算法是將記憶體劃分為一塊較大空間Eden和兩塊較小的Suvivor,一般比例是8:1:1。每次只是用Eden和Suvivor中的一塊,當回收時,將Eden和Suvivor中存活的物件複製到另一塊Suvivor中,再將Eden和使用的Suvivor清除掉。
標記壓縮演算法(標記整理)
標記-壓縮演算法與標記-清理演算法類似,只是後續步驟是讓所有存活的物件移動到一端,然後直接清除掉端邊界以外的記憶體
垃圾收集器
常見的垃圾收集器:
Serial:新生代收集器,單執行緒。
ParNew:新生代收集器,Serial的多執行緒版本,和CMS配合工作。
Parallel Scavenge:新生代,可以控制吞吐量。配合自適應調節策略,可以讓虛擬機器自動完成記憶體調優。
Serial Old:Serial老年代版本,單執行緒。
Parallel Old:Parallel Scavenge老年代版本,多執行緒
CMS:老年代收集器,特點:併發,低停頓,以獲取最短回收停頓時間為目標。基於標記-清除演算法。
CMS過程:
- 1初始標記 :標記GC Roots能直接關聯的物件,速度很快。
- 2併發標記 :進行GC Roots Tracing的過程,耗時長
- 3 重新標記 :修正併發標記期間不正確的標記記錄
- 4 併發清除
Minor GC和Full GC之間的區別
堆記憶體劃分為 Eden、和兩塊Survivor,JDK1.8移除了永久代。
- Minor GC 新生代GC: JAVA物件大多具備朝生夕滅的特性,所以Minor GC非常頻繁,回收速度也比較快。
- Full GC/Major GC 老年代GC: 速度一般比Minor GC慢很多。
記憶體分配策略
- 物件優先在新生代Eden區中分配,當Eden區沒有足夠空間時,虛擬機器發起Minor GC.
- 大物件直接進入老年代,大物件典型的就是很長的字串或陣列。
- 長期存活的物件進入老年代。