JVM快速調優手冊02:常見的垃圾收集器

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

如果說收集算法是內存回收的方法論,那么垃圾收集器就是內存回收的具體實現。

Java虛擬機規范中對垃圾收集器應該如何實現并沒有任何規定,因此不同的廠商、不同版本的虛擬機所提供的垃圾收集器都可能會有很大差別,并且一般都會提供參數供用戶根據自己的應用特點和要求組合出各個年代所使用的收集器。

2

HotSpot虛擬機的垃圾回收器


圖中展示了7種作用于不同分代的收集器,如果兩個收集器之間存在連線,就說明它們可以搭配使用。虛擬機所處的區域,則表示它是屬于新生代收集器還是老年代收集器。

概念理解


  1. 并發和并行
    這兩個名詞都是并發編程中的概念,在談論垃圾收集器的上下文語境中,它們可以解釋如下。

    • 并行(Parallel):指多條垃圾收集線程并行工作,但此時用戶線程仍然處于等待狀態。

    • 并發(Concurrent):指用戶線程與垃圾收集線程同時執行(但不一定是并行的,可能會交替執行),用戶程序在繼續運行,而垃圾收集程序運行于另一個CPU上。

  2. Minor GC 和 Full GC

    • 新生代GC(Minor GC):指發生在新生代的垃圾收集動作,因為Java對象大多都具備朝生夕滅的特性,所以Minor GC非常頻繁,一般回收速度也比較快。

    • 老年代GC(Major GC / Full GC):指發生在老年代的GC,出現了Major GC,經常會伴隨至少一次的Minor GC(但非絕對的,在Parallel Scavenge收集器的收集策略里就有直接進行Major GC的策略選擇過程)。Major GC的速度一般會比Minor GC慢10倍以上。

  3. 吞吐量
    吞吐量就是CPU用于運行用戶代碼的時間與CPU總消耗時間的比值,即吞吐量 = 運行用戶代碼時間 /(運行用戶代碼時間 + 垃圾收集時間)。
    虛擬機總共運行了100分鐘,其中垃圾收集花掉1分鐘,那吞吐量就是99%。

一、Serial收集器


Serial收集器是最基本、發展歷史最悠久的收集器,曾經(在JDK 1.3.1之前)是虛擬機新生代收集的唯一選擇。

2

  1. 特性:
    這個收集器是一個單線程的收集器,但它的“單線程”的意義并不僅僅說明它只會使用一個CPU或一條收集線程去完成垃圾收集工作,更重要的是在它進行垃圾收集時,必須暫停其他所有的工作線程,直到它收集結束。Stop The World

  2. 應用場景:
    Serial收集器是虛擬機運行在Client模式下的默認新生代收集器。

  3. 優勢:
    簡單而高效(與其他收集器的單線程比),對于限定單個CPU的環境來說,Serial收集器由于沒有線程交互的開銷,專心做垃圾收集自然可以獲得最高的單線程收集效率。

二、ParNew收集器


2

  1. 特性:
    ParNew收集器其實就是Serial收集器的多線程版本,除了使用多條線程進行垃圾收集之外,其余行為包括Serial收集器可用的所有控制參數、收集算法、Stop The World、對象分配規則、回收策略等都與Serial收集器完全一樣,在實現上,這兩種收集器也共用了相當多的代碼。

  2. 應用場景:
    ParNew收集器是許多運行在Server模式下的虛擬機中首選的新生代收集器。

    很重要的原因是:除了Serial收集器外,目前只有它能與CMS收集器配合工作。
    在JDK 1.5時期,HotSpot推出了一款在強交互應用中幾乎可認為有劃時代意義的垃圾收集器——CMS收集器,這款收集器是HotSpot虛擬機中第一款真正意義上的并發收集器,它第一次實現了讓垃圾收集線程與用戶線程同時工作。
    不幸的是,CMS作為老年代的收集器,卻無法與JDK 1.4.0中已經存在的新生代收集器Parallel Scavenge配合工作,所以在JDK 1.5中使用CMS來收集老年代的時候,新生代只能選擇ParNew或者Serial收集器中的一個。

  3. Serial收集器 VS ParNew收集器:
    ParNew收集器在單CPU的環境中絕對不會有比Serial收集器更好的效果,甚至由于存在線程交互的開銷,該收集器在通過超線程技術實現的兩個CPU的環境中都不能百分之百地保證可以超越Serial收集器。
    然而,隨著可以使用的CPU的數量的增加,它對于GC時系統資源的有效利用還是很有好處的。

三、Parallel Scavenge收集器


  1. 特性:
    Parallel Scavenge收集器是一個新生代收集器,它也是使用復制算法的收集器,又是并行的多線程收集器。

  2. 應用場景:
    停頓時間越短就越適合需要與用戶交互的程序,良好的響應速度能提升用戶體驗,而高吞吐量則可以高效率地利用CPU時間,盡快完成程序的運算任務,主要適合在后臺運算而不需要太多交互的任務。

  3. 對比分析:

    • Parallel Scavenge收集器 VS CMS等收集器:
      Parallel Scavenge收集器的特點是它的關注點與其他收集器不同,CMS等收集器的關注點是盡可能地縮短垃圾收集時用戶線程的停頓時間,而Parallel Scavenge收集器的目標則是達到一個可控制的吞吐量(Throughput)。
      由于與吞吐量關系密切,Parallel Scavenge收集器也經常稱為“吞吐量優先”收集器。

    • Parallel Scavenge收集器 VS ParNew收集器:
      Parallel Scavenge收集器與ParNew收集器的一個重要區別是它具有自適應調節策略。

      GC自適應的調節策略
      Parallel Scavenge收集器有一個參數-XX:+UseAdaptiveSizePolicy。當這個參數打開之后,就不需要手工指定新生代的大小、Eden與Survivor區的比例、晉升老年代對象年齡等細節參數了,虛擬機會根據當前系統的運行情況收集性能監控信息,動態調整這些參數以提供最合適的停頓時間或者最大的吞吐量,這種調節方式稱為GC自適應的調節策略(GC Ergonomics)。

四、Serial Old收集器


2

  1. 特性:
    Serial Old是Serial收集器的老年代版本,它同樣是一個單線程收集器,使用標記-整理算法。

  2. 應用場景:

    • Client模式
      Serial Old收集器的主要意義也是在于給Client模式下的虛擬機使用。

    • Server模式
      如果在Server模式下,那么它主要還有兩大用途:一種用途是在JDK 1.5以及之前的版本中與Parallel Scavenge收集器搭配使用,另一種用途就是作為CMS收集器的后備預案,在并發收集發生Concurrent Mode Failure時使用。

五、Parallel Old收集器


2

  1. 特性:
    Parallel Old是Parallel Scavenge收集器的老年代版本,使用多線程“標記-整理”算法。

  2. 應用場景:
    在注重吞吐量以及CPU資源敏感的場合,都可以優先考慮Parallel Scavenge加Parallel Old收集器。

    這個收集器是在JDK 1.6中才開始提供的,在此之前,新生代的Parallel Scavenge收集器一直處于比較尷尬的狀態。原因是,如果新生代選擇了Parallel Scavenge收集器,老年代除了Serial Old收集器外別無選擇(Parallel Scavenge收集器無法與CMS收集器配合工作)。由于老年代Serial Old收集器在服務端應用性能上的“拖累”,使用了Parallel Scavenge收集器也未必能在整體應用上獲得吞吐量最大化的效果,由于單線程的老年代收集中無法充分利用服務器多CPU的處理能力,在老年代很大而且硬件比較高級的環境中,這種組合的吞吐量甚至還不一定有ParNew加CMS的組合“給力”。直到Parallel Old收集器出現后,“吞吐量優先”收集器終于有了比較名副其實的應用組合。

六、CMS收集器


  1. 特性:
    CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標的收集器。目前很大一部分的Java應用集中在互聯網站或者B/S系統的服務端上,這類應用尤其重視服務的響應速度,希望系統停頓時間最短,以給用戶帶來較好的體驗。CMS收集器就非常符合這類應用的需求。

    2


    CMS收集器是基于“標記—清除”算法實現的,它的運作過程相對于前面幾種收集器來說更復雜一些,整個過程分為4個步驟:

    • 初始標記(CMS initial mark)
      初始標記僅僅只是標記一下GC Roots能直接關聯到的對象,速度很快,需要“Stop The World”。

    • 并發標記(CMS concurrent mark)
      并發標記階段就是進行GC Roots Tracing的過程。

    • 重新標記(CMS remark)
      重新標記階段是為了修正并發標記期間因用戶程序繼續運作而導致標記產生變動的那一部分對象的標記記錄,這個階段的停頓時間一般會比初始標記階段稍長一些,但遠比并發標記的時間短,仍然需要“Stop The World”。

    • 并發清除(CMS concurrent sweep)
      并發清除階段會清除對象。

    由于整個過程中耗時最長的并發標記和并發清除過程收集器線程都可以與用戶線程一起工作,所以,從總體上來說,CMS收集器的內存回收過程是與用戶線程一起并發執行的。

  2. 優點:
    CMS是一款優秀的收集器,它的主要優點在名字上已經體現出來了:并發收集低停頓

  3. 缺點:

    • CMS收集器對CPU資源非常敏感
      其實,面向并發設計的程序都對CPU資源比較敏感。在并發階段,它雖然不會導致用戶線程停頓,但是會因為占用了一部分線程(或者說CPU資源)而導致應用程序變慢,總吞吐量會降低。
      CMS默認啟動的回收線程數是(CPU數量+3)/ 4,也就是當CPU在4個以上時,并發回收時垃圾收集線程不少于25%的CPU資源,并且隨著CPU數量的增加而下降。但是當CPU不足4個(譬如2個)時,CMS對用戶程序的影響就可能變得很大。

    • CMS收集器無法處理浮動垃圾
      CMS收集器無法處理浮動垃圾,可能出現“Concurrent Mode Failure”失敗而導致另一次Full GC的產生。

      由于CMS并發清理階段用戶線程還在運行著,伴隨程序運行自然就還會有新的垃圾不斷產生,這一部分垃圾出現在標記過程之后,CMS無法在當次收集中處理掉它們,只好留待下一次GC時再清理掉。這一部分垃圾就稱為“浮動垃圾”。
      也是由于在垃圾收集階段用戶線程還需要運行,那也就還需要預留有足夠的內存空間給用戶線程使用,因此CMS收集器不能像其他收集器那樣等到老年代幾乎完全被填滿了再進行收集,需要預留一部分空間提供并發收集時的程序運作使用。要是CMS運行期間預留的內存無法滿足程序需要,就會出現一次“Concurrent Mode Failure”失敗,這時虛擬機將啟動后備預案:臨時啟用Serial Old收集器來重新進行老年代的垃圾收集,這樣停頓時間就很長了。

    • CMS收集器會產生大量空間碎片
      CMS是一款基于“標記—清除”算法實現的收集器,這意味著收集結束時會有大量空間碎片產生。

      空間碎片過多時,將會給大對象分配帶來很大麻煩,往往會出現老年代還有很大空間剩余,但是無法找到足夠大的連續空間來分配當前對象,不得不提前觸發一次Full GC。

七、G1收集器


2

  1. 特性:
    G1(Garbage-First)是一款面向服務端應用的垃圾收集器。HotSpot開發團隊賦予它的使命是未來可以替換掉JDK 1.5中發布的CMS收集器。與其他GC收集器相比,G1具備如下特點。

    • 并行與并發
      G1能充分利用多CPU、多核環境下的硬件優勢,使用多個CPU來縮短Stop-The-World停頓的時間,部分其他收集器原本需要停頓Java線程執行的GC動作,G1收集器仍然可以通過并發的方式讓Java程序繼續執行。

    • 分代收集
      與其他收集器一樣,分代概念在G1中依然得以保留。雖然G1可以不需要其他收集器配合就能獨立管理整個GC堆,但它能夠采用不同的方式去處理新創建的對象和已經存活了一段時間、熬過多次GC的舊對象以獲取更好的收集效果。

    • 空間整合
      與CMS的“標記—清理”算法不同,G1從整體來看是基于“標記—整理”算法實現的收集器,從局部(兩個Region之間)上來看是基于“復制”算法實現的,但無論如何,這兩種算法都意味著G1運作期間不會產生內存空間碎片,收集后能提供規整的可用內存。這種特性有利于程序長時間運行,分配大對象時不會因為無法找到連續內存空間而提前觸發下一次GC。

    • 可預測的停頓
      這是G1相對于CMS的另一大優勢,降低停頓時間是G1和CMS共同的關注點,但G1除了追求低停頓外,還能建立可預測的停頓時間模型,能讓使用者明確指定在一個長度為M毫秒的時間片段內,消耗在垃圾收集上的時間不得超過N毫秒。

    在G1之前的其他收集器進行收集的范圍都是整個新生代或者老年代,而G1不再是這樣。使用G1收集器時,Java堆的內存布局就與其他收集器有很大差別,它將整個Java堆劃分為多個大小相等的獨立區域(Region),雖然還保留有新生代和老年代的概念,但新生代和老年代不再是物理隔離的了,它們都是一部分Region(不需要連續)的集合。

    G1收集器之所以能建立可預測的停頓時間模型,是因為它可以有計劃地避免在整個Java堆中進行全區域的垃圾收集。G1跟蹤各個Region里面的垃圾堆積的價值大小(回收所獲得的空間大小以及回收所需時間的經驗值),在后臺維護一個優先列表,每次根據允許的收集時間,優先回收價值最大的Region(這也就是Garbage-First名稱的來由)。這種使用Region劃分內存空間以及有優先級的區域回收方式,保證了G1收集器在有限的時間內可以獲取盡可能高的收集效率。

  2. 執行過程:
    G1收集器的運作大致可劃分為以下幾個步驟:

    • 初始標記(Initial Marking)
      初始標記階段僅僅只是標記一下GC Roots能直接關聯到的對象,并且修改TAMS(Next Top at Mark Start)的值,讓下一階段用戶程序并發運行時,能在正確可用的Region中創建新對象,這階段需要停頓線程,但耗時很短。

    • 并發標記(Concurrent Marking)
      并發標記階段是從GC Root開始對堆中對象進行可達性分析,找出存活的對象,這階段耗時較長,但可與用戶程序并發執行。

    • 最終標記(Final Marking)
      最終標記階段是為了修正在并發標記期間因用戶程序繼續運作而導致標記產生變動的那一部分標記記錄,虛擬機將這段時間對象變化記錄在線程Remembered Set Logs里面,最終標記階段需要把Remembered Set Logs的數據合并到Remembered Set中,這階段需要停頓線程,但是可并行執行。

    • 篩選回收(Live Data Counting and Evacuation)
      篩選回收階段首先對各個Region的回收價值和成本進行排序,根據用戶所期望的GC停頓時間來制定回收計劃,這個階段其實也可以做到與用戶程序一起并發執行,但是因為只回收一部分Region,時間是用戶可控制的,而且停頓用戶線程將大幅提高收集效率。

八、總結


雖然我們是在對各個收集器進行比較,但并非為了挑選出一個最好的收集器。因為直到現在為止還沒有最好的收集器出現,更加沒有萬能的收集器,所以我們選擇的只是對具體應用最合適的收集器。這點不需要多加解釋就能證明:如果有一種放之四海皆準、任何場景下都適用的完美收集器存在,那HotSpot虛擬機就沒必要實現那么多不同的收集器了。

2


?

?

轉載于:https://my.oschina.net/gordonnemo/blog/3028955

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/536608.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/536608.shtml
英文地址,請注明出處:http://en.pswp.cn/news/536608.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

linux運維平臺工具,Linux運維自動化工具 Kickstart

簡介:批量安裝操作系統工具之 Kickstart ,RedHat 早前推出的產品( 不多說了,現在都玩 Cobbler 啦,見 http://www.linuxidc.com/Linux/2016-04/129977.htm )。測試環境:CentOS 6.6 x86_64 minimal一、安裝軟件包shell &…

PostgreSQL 并行查詢概述

2019獨角獸企業重金招聘Python工程師標準>>> PostgreSQL從9.6版本開始加入并行查詢,并在PostgreSQL10和PostgreSQL11分別做了大量加強工作。下面從: 何時啟用并行查詢功能并行查詢是如何工作的worker進程數量越多,查詢性能越高嗎三…

linux下得到date命令,linux下date命令獲得今天日期的用法

1。獲取今天日期的各類用法:oracle[roottest ~]# date %Y_%m_%d2016_05_22[roottest ~]# date %Y_%m_%d2016_05_22ide[roottest ~]# date "%Y_%m_%d"2016_05_22[roottest ~]# date %Y_%m_%d2016_05_22[roottest ~]# date "%Y_%m_%d"2016_05_22i…

Quarkus:一個Kubernetes原生Java框架

Red Hat發布了Quarkus,這是一個為GraalVM和OpenJDK HotSpot量身定制的Kubernetes原生Java框架。Quarkus的目標是使Java成為Kubernetes和無服務器環境中的領先平臺,為開發人員提供統一的反應式和命令式編程模型。 Quarkus利用Java開發人員使用的一系列庫&…

分區安裝linux,怎樣安裝Linux?

我的機子上裝了win2000,想裝個Linux可是在安裝時,竟然D 、E盤都不見了,win2000也進不去了我只得重裝2000,現在我都不敢裝Linux了請高手指點!|你最好用PQMAGIC先分區,大約2。5G空間就夠了,可以參…

linux scp傳輸文件命令

scp -r /opt/test root192.168.2.105:/opt 轉載于:https://www.cnblogs.com/LynnChen/p/10620576.html

pg10 10.3 1 linux64,Install Postgresql 10 In Ubutnu 16.04 LTS

PostgreSQL數據庫是一個高性能的全功能的開源關系型數據庫,這里講解一下如何在Ubuntu 16.04 LTS 下安裝 PostgreSQL 10。添加軟件源wget -q -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -sudo sh -c echo "deb http://apt.po…

nginx能訪問html靜態文件但無法訪問php文件

nginx.conf中紅框部分修改成你的實際網站根目錄轉載于:https://www.cnblogs.com/IT-Crowd/p/10626549.html

linux虛擬光驅掛載方法,Linux操作系統下虛擬光驅(iso)的掛載

1、掛載iso文件一般查看iso文件內容,只需要:#mount -t iso9660 -o loop xxx.iso /mnt/cdrom就可以在/mnt/cdrom下看到xxx.iso的內容。2、復制光盤為iso鏡像#dd if/dev/hdb ofxxx.iso或者#cp /dev/cdrom xxx.iso3、虛擬iso為設備#rm -rf /dev/cdrom //刪除…

[深度概念]·K-Fold 交叉驗證 (Cross-Validation)的理解與應用

個人主頁--> xiaosongshine.github.io/ 1.K-Fold 交叉驗證概念在機器學習建模過程中,通行的做法通常是將數據分為訓練集和測試集。測試集是與訓練獨立的數據,完全不參與訓練,用于最終模型的評估。在訓練過程中,經常會出現過擬合…

linux mariadb 升級,linux mariadb

linux mariadb轉載 一 安裝下載mariaDB MariaDB-5.5.29-rhel5-x86_64-common.rpm 和MariaDB-5.5.29-rhel5-x86_64-server.rpm 包,MariaDB-5.5.29-rhel5-x86_64-client.rpm2.然后再http.//yum。mariadb。org/ 找到 RPM-GPG-KEY-MariaDB 這個PGP文件,把文件放入到/etc…

Linux Note

日期:2019/3/31 內容:Linux學習筆記 一、Linux命令 ls -l 操作效果 第一列:文件權限 一共10位。 01(r)2(w)3(x)4(r)5(w)6(x)7(r)8(w)9(x)文件類型文件所有者權限 usr權限,u權限文件所有者所屬組成員的權限 group權限,g…

linux查看usb鼠標是否啟動,Linux USB鼠標驅動注解及測試

參考2.6.14版本中的driver/usb/input/usbmouse.c。鼠標驅動可分為多個部分:驅動加載部分、probe部分、open部分、urb回調函數處理部分。下文陰影部分為注解。一、 驅動加載部分static int __init usb_mouse_init(void){int retval usb_register(&usb_mouse_…

退役前的最后的做題記錄upd:2019.04.04

考試考到自閉&#xff0c;每天被吊打。 還有幾天可能就要AFO了呢。。。 Luogu3602&#xff1a;Koishi Loves Segments 從左向右&#xff0c;每次刪除右端點最大的即可。 [HEOI2014]南園滿地堆輕絮 答案一定是 \(\lceil \frac{max_{1\le i < j \le n}(a_i-a_j)}{2} \rceil\)。…

linux ssh-add,linux – 如何使ssh-add從文件讀取密碼?

根據您的發行版本和ssh-add的版本,您可以使用或不使用以這種方式從stdin讀取密碼的ssh-add的-p選項&#xff1a;cat passfile | ssh-add -p keyfile如果這不工作,您可以使用Expect,Unix工具使交互式應用程序非互動.你必須從你的包管理器安裝它.我為你準備了一個工具.只需將內容…

linux nginx F配置,linux下nginx的安裝及配置

1、安裝nginx前&#xff0c;咱們首先要確保系統安裝了g、gcc、openssl-devel、pcre-devel和zlib-devel軟件&#xff0c;可經過如圖所示命令進行檢測,若是以安裝咱們能夠經過圖二所示卸載&#xff1a;linuxyum install gcc-cyum -y install zlib zlib-devel openssl openssl--de…

你缺啥,你缺一個得力的辦公軟件

其實你缺啥我都知道&#xff0c;但是&#xff0c;我又不能給你發工資&#xff0c;還得你自己努力工作才行。不過我可以給你分享幾款好用的辦公軟件&#xff0c;對你在進行有效率的辦公會有很大幫助的。曲奇辦公是一款以文檔為載體的企業辦公管理應用。幫助企業快速實現業務標準…

C語言做一個表格的程序,用C語言畫個簡單表格

今天見到個題目&#xff0c;就把他做了&#xff0c;題目如下&#xff1a;在圖形環境中很容易做出漂亮的表格。但在控制臺環境中就比較困難了。有的時候可以用一些符號大略地模擬&#xff1a;(word文檔中可能不整齊&#xff0c;拷貝到記事本中看)-------------|abc |xyztt|…

深度學習框架PyTorch一書的學習-第四章-神經網絡工具箱nn

參考https://github.com/chenyuntc/pytorch-book/tree/v1.0 希望大家直接到上面的網址去查看代碼&#xff0c;下面是本人的筆記 本章介紹的nn模塊是構建與autograd之上的神經網絡模塊 除了nn外還會介紹神經網絡中常用的工具&#xff0c;比如優化器optim、初始化init等 1.nn.Mod…

高級語言程序設計c 華南理工,華南理工大學高級語言程序設計(C)期末練習題

.. 《高級語言程序設計(C)》練習題一&#xff0e;單項選擇題1.用C語言編制的源程序要變為目標程序必須要經過( )。(a) 解釋(b) 匯編(c) 編輯(d) 編譯2. 執行C程序時出現的“溢出”錯誤屬于( )錯誤。(a) 編譯(b) 連接(c) 運行(d) 邏輯3. 按C標識符的語法規定&#xff0c;合法的標…