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


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

HotSpot虛擬機中的垃圾收集器

7種作用於不同分代的收集器,如果兩個收集器之間存在連線,就說明它們可以搭配使用。

GC實現目標: 准確、高效、低停頓、空閑內存規整.

 

GC評價標准

在評估一個GC時,有幾個方面需要關注。

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

GC調優

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

響應時間

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

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

對於專注於最小響應時間的應用,長時間停頓是無法接受的。

吞吐量

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

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

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

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 並發清除  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM