JVM之垃圾收集算法及垃圾收集器詳解

JVM之垃圾收集算法及垃圾收集器詳解

一、垃圾回收算法

  • 標記清除算法
  • 複製算法
  • 標記壓縮算法(Mark-Compact)
  • 分代算法

1.1 標記清除算法

標記清除算法將垃圾回收分爲兩個階段:標記階段清除階段
標記階段:首先經過根節點,標記全部從根節點開始的可達對象。未被標記的對象就是未被引用的垃圾對象。
清除階段:清除全部未被標記的對象。
標記清除算法可能產生的最大問題是空間碎片
注意:標記清除算法先經過根節點標記全部可達對象,而後清除全部不可達對象,完成垃圾回收。算法

1.2 複製算法

eden ===> from to,就是使用的複製算法
優勢:不會產生碎片
缺點:浪費空間多線程

1.3 標記壓縮算法

標記壓縮算法是一種老年代的回收算法。併發

1.4 分代收集算法

新生代能夠用複製算法。
老年代可使用標記-清除算法標記-整理算法jvm

二、垃圾收集器

  • 串行收集器
  • 並行收集器
  • CMS
  • G1

2.1 串行回收器

串行回收器是指使用單線程進行垃圾回收的回收器。性能

2.1.1 新生代串行回收器

串行回收器主要有兩個特色:線程

  • 它僅僅使用單線程進行垃圾回收
  • 它是獨佔式的垃圾回收

在串行收集器進行垃圾回收時,Java應用程序中的線程都須要暫停,等待垃圾回收的完成。這種現象稱之爲Stop-The-World。在實時性要求較高的應用場景中,這種現象每每是不能被接受的。code

新生代串行處理器使用複製算法對象

使用-XX:+UseSerialGC參數能夠指定使用新生代串行收集器和老年代串行收集器。內存

2.1.2 老年代串行回收器

老年代串行收集器使用的是標記壓縮算法。和新生代串行收集器同樣,它也是一個串行的、獨佔式的垃圾回收器。工作流

若是要啓動老年代串行回收器,能夠嘗試使用如下參數:

  • -XX:+UseSerialGC:新生代、老年代都使用串行回收器
  • -XX:+UseParNewGC:新生代使用ParNew回收器,老年代使用串行收集器
  • -XX:+UseParallelGC:新生代使用ParallelGC回收器,老年代使用串行收集器

2.2 並行收集器

它只是在串行回收器上作了改進,使用多個線程同時進行垃圾回收。

2.2.1 新生代ParNew回收器

它是獨佔式的。
在併發能力比較強的CPU上,它產生的停頓時間要短於串行回收器,而在單CPU或者併發能力較弱的系統中,並行回收器的效果不會比串行回收器好,因爲多線程的壓力,它的實際表現極可能比串並回收器差。

啓動新生代ParNew回收器:

  • -XX:+UseParNewGC:新生代使用ParNew回收器,老年代使用串行回收器。
  • -XX:+UseConcMarkSweepGC:新生代使用ParNew回收器,老年代使用CMS。

ParNew回收器的線程數量能夠經過-XX:ParallelGCThreads參數指定。

2.2.2 新生代ParallelGC回收器

新生代ParallelGC回收器關注系統吞吐量,使用複製算法

啓動新生代ParallelGC回收器:

  • -XX:+UseParallelGC:新生代使用ParallelGC回收器,老年代使用串行回收器。
  • -XX:+UseParallelOldGC:新生代使用ParallelGC回收器,老年代使用ParallelOldGC。

ParallelGC回收器提供了兩個重要的參數用於控制系統的吞吐量:

  • -XX:MaxGCPauseMillis:設置最大垃圾收集停頓時間
  • -XX:GCTimeRatio:設置吞吐量大小

這是它與ParNew回收器的一個不一樣之處,另一個不一樣之處是它還支持一種自適應的GC調整策略。使用-XX:+UseAdaptiveSizePolicy能夠打開自適應GC策略。

2.2.3 老年代ParallelOldGC回收器

老年代ParallelOldGC回收器也是一種多線程並行的收集器。它也是一種關注吞吐量的收集器。它使用標記壓縮算法,它在JDK1.6中才可使用。

使用-XX:+UseParallelOldGC能夠在新生代使用ParallelGC回收器,老年代使用ParallelOldGC回收器。參數-XX:ParallelGCThreads也能夠用於設置垃圾回收時的線程數量。

2.3 CMS收集器

它是非獨佔的。

ParallelGCParallelOldGC不一樣,CMS回收器主要關注於系統停頓時間。CMS是Concurrent Mark Sweep的縮寫,意爲併發標記清除,從名稱上就能夠得知,它使用的是標記清除算法,同時它又是一個使用多線程並行回收的垃圾回收器。

2.3.1 CMS主要的設置參數
  • -XX:-CMSPrecleaningEnabled
    關閉預清理
  • -XX:+UseConcMarkSweepGC
    啓動CMS回收器的參數。CMS是多線程回收器,設置合理的工做線程數量也對系統性能有重要的影響。(同時也表示新生代使用ParNewGC
  • -XX:CMSInitiatingOccupancyFraction
    指定當老年代空間使用率達到多少時,進行一次CMS垃圾回收。
  • -XX:+UseCMSCompactAtFullCollection
    這個開關可使CMS在垃圾收集完成後,進行一次內存碎片整理,內存碎片的整理不是併發並行的。
  • -XX:CMSFullGCsBeforeCompaction
    能夠用於設定進行多少次CMS回收後,進行一次內存壓縮。

注意:
併發是指收集器和應用線程交替執行。
並行是指應用程序中止,同時由多個線程一塊兒執行GC。
所以並行回收器不是併發的,由於並行回收器執行時,應用程序徹底掛起,不存在交替執行的步驟。CMS回收器是一個關注停頓的垃圾收集器。同時CMS回收器在部分工做流程中,能夠與用戶程序同時運行,從而下降應用程序的停頓時間。

2.3.2 有關Class的回收

在使用CMS回收器時,若是須要回收Perm區,那麼默認狀況下,仍是須要觸發一次Full GC的。若是但願使用CMS回收Perm區,則必需要打開-XX:+CMSClassUnloadingEnabled開關,若是條件容許,那麼系統會使用CMS的機制回收Perm區Class數據。

2.4 G1回收器

G1回收器是在JDK1.7中正式使用的全新垃圾回收器,從長期目標來看,它是爲了取代CMS回收器。

從分代上看,G1依然屬於分代垃圾回收器,它會區分年輕代老年代,依然有eden區和survivor區,但從堆的結構上看,它並不要求整個eden區,年輕代或者老年代都連續。它使用了分區算法

做爲CMS的長期替代方案,G1同時使用了全新的分區算法,其特色以下:

  • 並行性:G1在回收期間,能夠由多個GC線程同時工做,有效利用多核計算能力。
  • 併發性:G1擁有與應用程序交替執行的能力,部分工做能夠和應用程序同時執行,所以通常來講,不會在整個回收期間徹底阻塞應用程序。
  • 分代GC:G1依然是一個分代收集器,可是和以前回收器不一樣,它同時兼顧年輕代和老年代。
  • 空間整理:G1在回收過程當中,會進行適當的對象移動,不像CMS,只是簡單地標記清理對象,在若干次GC後,CMS必須進行一次碎片整理。而G1不一樣,它每次回收都會有效地複製對象,減小空間碎片。
  • 可預見性:因爲分區的緣由,G1能夠只選取部分區域進行內存回收,這樣縮小了回收的範圍,所以對於全局停頓也能獲得較好的控制。
2.4.1 G1的內存劃分和主要收集過程

G1的手機過程可能有4個階段:

  • 新生代GC
  • 併發標記週期
  • 混合收集
  • 若是須要,可能會進行Full GC
相關文章
相關標籤/搜索