1. 程式人生 > >性能測試三十五:jvm垃圾回收-GC

性能測試三十五:jvm垃圾回收-GC

並行 ria ima 指向 loader 串行 順序分配 分配 利用

垃圾回收-GC

三個問題
  哪些內存需要回收?
  什麽時候回收?
  如何回收?

YoungGC和FullGC:

  新生代引發的GC叫YoungGC
  老年代引發的GC叫FullGC

 FullGC會引起整個Jvm的用戶線程暫停,待垃圾回收完畢後,才繼續運行

引用的定義:
如果reference類型的數據中存儲的數值代表的是另外一塊內存的起始地址,就稱這塊內存代表一個引用

對象存活狀態:

確定對象“存活”還是“死去”:以下兩種算法原理都一樣,就是看當前這個對象,是否有引用正在指向它,如果有,就是還有用的,如果沒有,就清除

  第一種:引用計數算法(已被廢棄):

    如果當前對象有一個引用正在指向它,則在其對應的計數器上+1,統計完後計數器上為0的就代表沒用的對象,進行清除


  第二種:根搜索算法(GC Roots):

    先找到對象,再根據對象去搜索,看有沒有引用正指向它,如果有,就是還有用的,如果沒有,就清除

永久代的垃圾回收:

永久代回收“性價比”比較低,因為裏面放的都是靜態的對象,都是有用的,無法回收,就算觸發了一次回收,占用內存還是不會變
主要回收
  廢棄的常量
  無用的類
    類的所有實例都已經被回收
    加載該類的ClassLoader已經被回收
    該類的Class對象沒有在任何地方被引用

   
堆垃圾回收算法:

1、標記-清除算法

以兩種狀態個所有對象分類,然後清除掉可回收的部分

特點:
  分為“標記”和“清除”兩個階段
  標記完成後,統一回收
缺點:
  效率,標記和清除過程效率都不高
  空間,標記清除後會產生大量不連續的內存碎片

技術分享圖片

2、復制算法

把內存分為ab兩塊,觸發垃圾回收的時候,直接把a裏面可用的對象有序的復制到b裏面,並清空a(和新生代的原理一樣)

特點:
  內存分為相等的兩塊
  當一塊內存用完,將存活對象復制到另外一塊中,原內存一次性清理掉
  復制時按照順序分配內存,無內存碎片問題
  新生代使用此算法
缺點:
  將內存分為兩半,利用率低

技術分享圖片

3、標記-壓縮算法

根據標記清除算法改良而來

特點:
  先對存活對象進行標記
  讓所有存活對象向一邊移動
  清理掉存活對象邊界外的所有內存

註:老年代使用此算法

技術分享圖片

4、分代收集算法

當代的商業虛擬機都采用“分代收集”
根據對象的存活周期的不同將內存劃分成幾塊,一般Java堆分為新生代和老年代
新生代采用復制算法
老年代采用標記-壓縮算法

垃圾收集器

以上的所有算法,都只是理念,而垃圾收集器是內存回收算法的具體實現,沒有完美的收集器

Jvm不同的區域可以采用不同的垃圾收集器組合,主要有:
1、Serial收集器(串行)

  單線程收集器
  用戶線程全部停止(Stop the world)
  Client模式下,新生代默認收集器
  優點:簡單、高效

技術分享圖片

2、ParNew收集器(並行)

  並行收集器,Serial收集器的多線程版本
  Server模式下Jvm默認的新生代收集器
  默認開啟的垃圾回收線程與cpu核數一致

技術分享圖片

3、CMS收集器(並發)

並發收集器(ConcurrentMarkSweep)
采用了標記-清除算法
並發收集、低停頓
缺點:
  消耗cpu
  會產生內存碎片
  浮動垃圾(Concurrent Mode Failure

技術分享圖片

4、G1收集器

性能測試三十五:jvm垃圾回收-GC