深刻探究jvm之GC的參數調優

  在上一篇博客記錄了GC的算法及種類,這篇博客主要記錄一下GC的參數如何調整以提升jvm的性能。算法

1、堆的回顧:多線程

  

 

                         

  堆的內存空間整體分爲新生代和老年代,老年代存放的老年對象,新構造的對象分配在eden區中(棧上分配及新生代內存不足的狀況除外)。在通過GC以後,倖存下來的對象會被分配到倖存代中,s0與s1是兩塊徹底相同的內存區域,採用複製算法,在迭代後交換內存空間。通過若干次GC後,仍然未被回收的對象會被分配到老年代中。併發

2、GC參數--串行收集器(Serial)jvm

   串行收集器有如下幾個特色:工具

  1)最古老、最穩定性能

  2)效率高測試

  3)可能產生較長時間的停頓,只是用一個線程進行回收,沒法發揮多核CPU的優點。(全局停頓在上一篇有介紹過)網站

  經過-XX:+UseSerialGC參數啓用,啓用以後,新生代和老年代會使用串行回收,新生代會採用複製算法,老年代會使用標記-壓縮算法。(參見上一篇博客)spa

  串行回收器的示意圖以下:線程

  參數分別記錄了新生代和老年代的回收狀況。

3、GC參數--並行收集器(PerNew)

  PerNew有如下幾個特色:

  1)是Serial收集器新生代的並行版本

  2)採用的是複製算法

  3) 是多線程運行的,須要多核CPU的支持。

  經過-XX:+UsePerNewGC參數啓用,啓用以後,新生代採用並行回收,而老年代仍然使用串行回收,採用複製算法。能夠經過-XX:ParallelGCThreads參數來限制線程的數量;

  經過-XX:MaxGCPauseMills參數控制最大停頓時間,單位是毫秒;GC會盡力保證回收時間不超過設定值;

  經過-XX:GCTimeRatio參數控制收集時間佔總時間的比,取值範圍是0-100;默認是1,即最大容許1%時間用來作GC。

  上述兩個參數是矛盾的,由於停頓時間和吞吐量不可能同時調優的。GC的次數減小,必然致使單次停頓的時間變長,反之亦然;所以在權衡參數時要抓住性能瓶頸。

  並行回收器的示意圖以下:

  須要注意的一點是,並行收集器只在多核CPU的狀況下能提高性能,同時要控制好線程數,不然效率反而打折扣。

4、Paraller收集器

  Paraller收集器的特色以下:

  1)相似於ParNew收集器

  2)新生代採用複製算法,老年代使用標記-壓縮算法。

  3)更加關注於吞吐量

  -XX:UseParallerGC參數:使用Paraller收集器,新生代採用並行收集,老年代採用串行收集;

  -XX:UseParallerOldGC參數:使用Paraller收集器,新生代和老年代都採用並行收集。

  Paraller收集器示例圖:

 5、CMS收集器(Concurrent Mask Sweep)

  主要的特色以下:

  1)採用的是標記-清除算法

  2)與標記-壓縮算法相比,在併發階段(與應用程序線程同時執行)會下降吞吐量。

  3)老年代的收集器,並不影響新生代收集器,新生代仍然採用ParNew收集器。

  經過-XX:UseConcMarkSweepGC參數啓用。

  CMS運行過程比較複雜,着重實現了標記的過程,可分爲:

  ①初始標記:根對象能夠直接關聯到對象(速度很快);

  ②併發標記:同應用程序線程同時進行,標記全部的對象;

  ③從新標記:因爲併發標記時,應用程序線程仍然在運行,所以在正式清理前,須要再次作修正;

  ④併發清除:基於以上的標記結果,直接清理對象。

  注意,在併發標記階段,一樣會產生全局停頓現象,只不過是儘量的減小了全局停頓的時間,在應用程序運行過程當中,會一直產生垃圾,沒法進行標記。

  CMS收集器示例圖以下:

  因爲在一些標記過程當中與應用程序並行,以保證可用對象的地址不發生改變,因此只能簡化標記算法而採用標記-清除算法。另外,CMS收集器會影響系統總體的吞吐量,如在用戶線程運行的過程當中,會佔用CPU進行GC操做;同時還存在清理不完全的狀況,在一些標記的過程當中,用戶的應用程序仍然會產生新的垃圾不會被標記。

  注意,由於和用戶的應用程序併發,不能在空間快滿時才進行清理操做,經過-XX:CMSInitiatingOccupancyFraction參數設置觸發GC的閾值,若是內存預留的空間不足,就會引發concurrent mode failure。發生錯誤的後備方法是,經過串行收集器進行收集,但會產生比較長時間的停頓。

  標記-清除算法會產生碎片空間,所以咱們須要進行碎片整理:

  經過-XX:UseCMSCompactAtFullCollection參數使在進行FullGC以後進行一次整理,這個整理過程是獨佔的,會引發停頓時間變長;

  經過-XX:CMSFullGCsBeforeCompaction參數設置進行幾回FullGC以後進行一次碎片整理;

  經過-XX:ParallelCMSThreads設定CMS的線程數量。

6、GC參數整理:

  -XX:+UseSerialGC:在新生代和老年代使用串行收集器;

  -XX:SurvivorRatio:設置eden區大小和survivor區大小的比例;

  -XX:NewRatio:設置新生代和老年代的大小比例;

  -XX:+UseParNewGC:在新生代使用並行收集器;

  -XX:+UseParellelGC:新生代使用並行回收收集器;

  -XX:+UseParallelOldGC:老年代使用並行回收收集器;

  -XX:ParallelGCThreads:設置用於垃圾回收的線程數;

  -XX:+UseConcMarkSweepGC:新生代使用並行收集器,老年代使用CMS+串行收集器;

  -XX:ParallelCMSThreads:設定CMS的線程數量;

  -XX:CMSInitiatingOccupancyFraction:設置CMS收集器在老年代空間被使用多少後被觸發;

  -XX:+UseCMSCompactAtFullCollection:設置CMS收集器在完成垃圾收集後是否要進行一次內存的碎片整理;

  -XX:CMSFullGCsBeforeCompaction:設定進行多少次CMS垃圾回收以後進行一次內存壓縮;

  -XX:+CMSClassUnloadingEnabled:容許對類元數據進行回收;

  -XX:CMSInitiatingPermOccupancyFraction:當永久區佔用率達到這一百分比時,啓用CMS回收;

  -XX:UseCMSInitiatingOccupancyOnly:只有到達閾值的時候才進行CMS回收。

 7、GC參數實例:

  環境:Tomcat七、JSP網站、JDK六、測試網站的吞吐量及延時。

  工具:Jmeter,創建10個線程,每一個線程請求Tomcat 1000次 共1w次。

  目的:讓Tomcat有一個不錯的吞吐量。

  結構:Tomcat與Jmeter分開部署,防止Jmeter對Tomcat的性能產生影響。

    

 一、參數:set CATALINA_OPTS=-server -Xloggc:gc.log -XX:+PrintGCDetails -Xms32M -Xmx32M -XX:+HeapDumpOnOutOfMemeryError -XX:+UseSerialGC -XX:PermSize=32M

  

二、參數:set CATALINA_OPTS=-Xmx512M -XX:MaxPermSize=32M -Xloggc:gc.log -XX:PrintGCDetails

  將最大堆內存改成512m,結果FullGC發生不多,基本上都是MinorGC。吞吐量由540提升到了650,同時堆大小也在自動拓展,由開始的15872K拓展到38秒的60456K。

三、參數:set CATALINA_OPTS=-Xmx512M -Xms=64M -XX:MaxPermSize=32M -Xloggc:gc.log -XX:PrintGCDetails

  將堆內存的初始大小設置爲64M,GC數量減小,大部分都是MinorGC.吞吐量由651提高到了674。

四、參數:set CATALINA_OPTS=-Xmx512M -Xms=64M -XX:MaxPermSize=32M -Xloggc:gc.log -XX:PrintGCDetails -XX:+UseParallelGC -XX:+UseParallelOldGC

   -XX:ParallelGCThreads

  新生代和老年代都使用並行回收收集器,GC本來壓力不大,因此影響很小。

五、參數:set CATALINA_OPTS=-Xmx40M -Xms40M -XX:MaxPermSize=32M -Xloggc:gc.log -XX:PrintGCDetails

  減小堆大小,增長GC壓力,默認使用串行回收收集器,吞吐量爲646。

六、參數:set CATALINA_OPTS=-Xmx40M -Xms40M -XX:MaxPermSize=32M -Xloggc:gc.log -XX:PrintGCDetails -XX:+UseParallelOldGC -XX:ParallelGCThreads

   減小堆大小,增長GC壓力,老年代使用並行回收收集器,吞吐量由646提升到了685。

七、參數:set CATALINA_OPTS=-Xmx40M -Xms40M -XX:MaxPermSize=32M -Xloggc:gc.log -XX:PrintGCDetails -XX:+UseParNewGC

   減小堆大小,增長GC壓力,新生代使用並行回收收集器,吞吐量由685降低到了660。可見老年代的GC回收機制對系統性能影響更大一些。

八、不添加任何參數,使用JDK6與JDK7對比

  發現JDK版本對於系統性能影響不容忽視。升級JDK版本可能會帶來額外的性能提高!

相關文章
相關標籤/搜索