深刻理解JVM 垃圾收集器(上)

  • HotSpot虛擬機中的垃圾收集器
  • GC評價標準
  • GC調優
    • 響應時間
    • 吞吐量
  • 1.新生代收集器
    • Serial收集器
    • ParNew收集器
    • Parallel Scavenge收集器
  • 2.老年代收集器
    • Serial Old收集器
    • Parallel Old收集器
    • CMS收集器(Concurrent Mark Sweep)

HotSpot虛擬機中的垃圾收集器

7種做用於不一樣分代的收集器,若是兩個收集器之間存在連線,就說明它們能夠搭配使用。java

GC實現目標: 準確、高效、低停頓、空閒內存規整.算法

 

GC評價標準

在評估一個GC時,有幾個方面須要關注。數據庫

  • GC的停頓時間: 大部分GC執行時須要將應用程序中止以便內存保持一個一致的狀態來進行回收,這會對應用程序的執行性能形成影響。
  • GC的吞吐量: 在不面向用戶的應用程序中,可能並不關注停頓時間,而是關注整體的執行效率,這時GC的吞吐量能夠理解爲回收必定內存所需的時間。

GC調優

java應用調優通常關注兩個指標:響應時間和吞吐量。api

響應時間

響應時間指的是應用對請求的響應時間,如:多線程

  • 一個桌面應用對時間的響應時間
  • 網站返回一個頁面的時間
  • 數據庫查詢結果返回時間

對於專一於最小響應時間的應用,長時間停頓是沒法接受的。併發

吞吐量

吞吐量專一於應用在一段時間的的最大工做量。如:app

  • 給定時間內完成的事物數
  • 每小時批處理程序可以完成的任務
  • 每小時數據庫能夠完成的查詢操做數

較長停頓時間在此狀況下是能夠接受的。比起低響應時間,吞吐量優先應用更看重一段時間內的表現。ide

1.新生代收集器

Serial收集器

 

 
工做區域
單線程/多線程
垃圾收集算法
 

Serial收集器性能

(Stop the World)網站

新生代 單線程 複製算法

Client模式下的默認新生代收集器。

進行垃圾收集時,必須Stop the world,直到它收集結束。

-XX:+UseSerialGC

 

ParNew收集器

 
工做區域
單線程/多線程
垃圾收集算法
 

ParNew收集器

(Serial收集器的多線程版本)

(Stop the World)

新生代 多線程 複製算法 Server模式下的默認新生代收集器

 

Parallel Scavenge收集器

 
工做區域
單線程/多線程
垃圾收集算法
 

Parallel Scavenge收集器

(Stop the World)

新生代 多線程 複製算法

吞吐量優先收集器

目標:控制吞吐量

吞吐量=運行用戶代碼時間/(運行用戶代碼時間+垃圾收集時間)

吞吐量越高說明CPU時間利用率越高。

JVM參數:

-XX:MaxGCPauseMillis 控制最大垃圾收集時間

-XX:GCTimeRatio 控制吞吐量大小

-XX:+UseParallelGC -XX:+UseParallelOldGC

 

2.老年代收集器

Serial Old收集器

 
做用區域
單線程/多線程
垃圾收集算法
 

Serial Old收集器

(Stop the World)

老年代 單線程 標記整理算法 這個收集器的主要意義也是在於給Client模式下的虛擬機使用。

若是在Server模式下,主要兩大用途:

(1)在JDK1.5以及以前的版本中與Parallel Scavenge收集器搭配使用

(2)做爲CMS收集器的後備預案,在併發收集發生Concurrent Mode Failure時使用

 

 

Parallel Old收集器

 
做用區域
單線程/多線程
垃圾收集算法
 

Parallel Old收集器

(Stop the World)

老年代 多線程 標記整理算法

Parallel Old 是Parallel Scavenge收集器的老年代版本。這個收集器在1.6中才開始提供。

在JDK1.5以及以前的版本中,Parallel Scavenge+Serial Old(單線程),沒法充分利用多CPU的處理能力。1.6以後,終於有了名副其實的「吞吐量優先「收集器組合:Parallel Scavenge + Parallel Old。

 

CMS收集器(Concurrent Mark Sweep)

 
做用區域
單線程/多線程
垃圾收集器算法
 
CMS收集器 老年代 多線程 標記-清除算法

目標:最短回收停頓時間

優勢:併發收集,低停頓

缺點:

1)CPU資源敏感。

在併發階段,雖然不會致使用於線程停頓。但會由於佔用了一部分CPU資源,致使用戶應用程序變慢,吞吐量下降。

2)沒法處理浮動垃圾

併發清理階段,用戶線程仍舊在運行併產生垃圾,這些產生的垃圾這次收集沒法清理。

所以,須要預留一部份內存用於併發清理時用戶程序使用。

解決方法:

當預留的內存不夠時,將發生Concurrent Mode Failure,JVM啓動後備預案,臨時啓用Serial Old進行老年代垃圾收集

-XX:CMSInitiatingOccupancyFraction

3)內存碎片問題

解決方法:

-XX:CMSFullGCsBeforeCompaction 設置執行多少次不帶壓縮的Full GC後,運行一次帶壓縮的

(默認爲0,表示每次Full GC都進行碎片整理)

CMS在老年代的整個過程分爲4個步驟:

 
階段
描述
1

初始標記

(Stop the World)

僅僅標記GC Roots能直接關聯到的對象,速度很快
2

從新標記

(Stop the World)

修正併發標記階段因用戶程序繼續運行而致使標記發生變更的那一部分標記記錄。此階段比初始標記階段稍長,但遠比並發標記階段的時間短。
3 併發標記 對GC Roots非直接關聯到的對象進行標記,在此階段,併發標記線程與用戶線程併發執行,標記可能發生變更
4 併發清除
相關文章
相關標籤/搜索