JVM配置CMS調優實戰筆記

一、背景說明

       由於原有項目未進行JVM配置,全部是用默認JVM配置,在壓測過程中TP99慘不忍睹,Young gc使用PS Scavenge,Full gc使用PS MarkSweep

二、JVM基礎知識

       1) 虛擬機內存模型:
           程序計數器、虛擬機棧、本地方法棧、JVM堆、方法區(粗略理解包含永久代)

        2) 垃圾收集算法:
            標記-清除、複製、標記-壓縮、分代收集算法

        3) jvm堆區分代:
             Eden(年輕代-伊甸園區)、Survivor0(年輕代-存活1區)、Survivor1(年輕代-存活2區)、Old Generation(老年代區)

        4) 垃圾收集器分類:
            Serial : 年輕代、串行、複製算法,默認年輕代收集器, -XX:+UseSerialGC 手動指定年輕代使用Serial收集器 
            Serial Old :老年代、串行、標記-清除、默認老年代收集器、 -XX:+UseSerialGC 手動指定老年代使用Serial收集器
            ParNew :年輕代,並行、複製算法、常用於多核CPU機器上,-XX:+UseParNewGC 手動指定年輕代使用ParNew收集器,可配合CMS收集器使用
            Parallel:年輕代、並行、複製算法、吞吐量優先,-XX:+UseParallelGC手動設置年輕代使用Parallel收集器,-XX:+GCTimeRatio 0~100 手動設置吞吐量大小,-XX:+MaxGCPauseMills 收到設置最大垃圾收集停頓時間
            Parallel Old:老年代、並行、複製算法、吞吐量優先,-XX:+UseParallelOldGC 手動設置年輕代、老年代都使用Parallel收集器
            CMS:老年代、並行、 標記-清除、高響應低延遲,-XX:+UseConcMarkSweepGC 手動設置老年代使用CMS收集器
            G1:使用Region區間貫穿年輕代和老年代,可以將年輕代、老年代理解爲標籤,而GC回收就相當於是在爲每個Region區間進行貼標籤的過程。根據回收情況將Region區間定爲年輕代和老年代(未在實戰中使用過,不做過多介紹)。
            G1相關說明可參見:https://blog.csdn.net/TimerBin/article/details/97148182

         5)Young GC/Full GC
             Young GC:Minor GC 對年輕代空間進行回收,-Xmn1024M 手動指定年輕代內存上限值
              Full GC:Major GC 對老年代空間進行回收,在進行Major GC之前會優先觸發Minor GC

三、JVM常用配置參數

        1) -Xmn: 新生代內存上限值
        2) -Xms: 整個堆區初始內存分配的大小
        3) -Xmx: 整個堆區內存分配的最大上限,推薦-Xms和-Xmx設置等同大小,避免動態回收消耗資源
        4) -XX:+HeapDumpOnOutOfMemoryError 當出現OOM時,打印堆轉儲dump文件
        5) -XX:HeapDumpPath= 指定堆轉儲dump文件存儲路徑
        6) -XX:MaxTenuringThreshold=5 : 手動設置對象在新生代中存活年齡(存活次數),默認15次
        7) -XX:SurvivorRatio=6 : Eden區與Survivor0、Survivor1區的大小比值,一般設置爲6,Eden:S0:S1=6:1:1
        8) -XX:PretenureSizeThreshold 手動指定對象大小,當對象達到指定大小時直接存放到老年代中,由於新生代大多使用複製算法,爲了節省複製消耗
         9) -XX:+UseParNewGC : 手動指定新生代使用 ParNew 收集器
         10) -XX:+UseConcMarkSweepGC : 手動指定老年代使用CMS收集器
         11) -XX:PermSize=512M 指定非堆區域(永久代)初始內存分配大小, JDK 1.7 及以下生效
         12) -XX:MaxPermSize= 1024M 指定非堆區域(永久代)內存分配的最大上限,JDK1.7 及以下生效
         13) -XX:+UseCMSInitiatingOccupancyOnly : Hotspot會根據成本計算決定是否需要執行CMS收集器,可手動設置-XX:+UseCMSInitiatingOccupancyOnly關閉計算策略,強制使用CMS 收集器
         14)  -XX:+CMSClassUnloadingEnabled : 手動指定CMS 收集器對非堆區域永久代進行回收,默認永久代不回收
         15) -XX:CMSInitiatingOccupancyFraction=80 : 手動指定當老年代已用空間達到80%時,觸發老年代回收(默認92%)
         16) -XX:CMSInitiatingPermOccupancyFraction=80  : 手動指定當永久代已用空間達到80%時,觸發永久代回收(默認92%)
         17) -XX:+DisableExplicitGC : 手動配置禁止使用外部調用System.gc 來進行觸發垃圾回收
         18) -XX:+UseCMSCompactAtFullCollection : 在進行Full GC時對內存進行壓縮,JDK1.6以前不需要配置,默認開啓
         19) -XX:CMSFullGCsBeforeCompaction=2 : 與-XX:+UseCMSCompactAtFullCollection 關聯使用標識着每經過多少次Full GC 觸發對內存進行一次壓縮,默認是0次
          20) -XX:-CMSParallelRemarkEnabled : 手動配置開啓並行標記,節省年輕代標記時間,JDK1.6以前不需要配置,默認開啓
          21) -Xnoclassgc  : 關閉CLASS的垃圾回收功能,默認20分鐘這個class未被使用,虛擬機會卸載這個類。再次使用時重新加載

四、JVM配置小記

linux機器配置:4核8G

問題一

原有JVM配置參數:

-XX:PermSize=512M -XX:MaxPermSize=1024M -XX:+HeapDumpOnOutOfMemoryError -XX:+DisableExplicitGC 

遇到的問題:

  • full gc 執行次數較多,影響用戶體驗
  • 在full gc執行過程中,導致sql執行超時,被數據庫慢SQL命中

可能的原因:

  • 使用默認年輕代和老年代回收器,串行GC,stop-the-world時間較長
  • 使用了默認的存活次數15,增加了在Eden和Survivor區進行復制回收成本
  • 年輕代大小或者年輕代中Eden區與Survivor0、Survivor1空間分配不合理。如果Eden區太小會導致大於Eden區一半對象直接儲存到老年代,增加老年代的使用情況

優化後配置:

-Xmx6144M -Xms6144M -XX:PermSize=512M -XX:MaxPermSize=1024M -XX:+HeapDumpOnOutOfMemoryError -XX:+DisableExplicitGC -XX:SurvivorRatio=6 -XX:MaxTenuringThreshold=5 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC

問題二

使用問題一優化後JVM配置:

遇到的問題:

  • yong gc 次數增多,full gc次數近乎爲零
  • 由於full gc次數減少,隨時間推移,堆內存使用量會持續增長,觸發堆內存使用情況報警,目前配置的堆內存使用90%就會報警。

可能的原因:

  • full gc執行次數減少,導致老年代未進行回收
  • 未開啓永久點緩存回收

優化後配置:

 -Xmx6144M -Xms6144M -XX:PermSize=512M -XX:MaxPermSize=1024M -XX:+HeapDumpOnOutOfMemoryError -XX:+DisableExplicitGC -XX:SurvivorRatio=6 -XX:MaxTenuringThreshold=5 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly  -XX:+CMSClassUnloadingEnabled -XX:CMSInitiatingOccupancyFraction=85   -XX:CMSInitiatingPermOccupancyFraction=85

五、總結

    沒有最優的JVM配置,只有最適合的JVM配置,需要結合系統的類型(worker任務、MQ消費、對外接口、WEB平臺)和對JVM回收情況的監控,逐步對JVM配置進行調優,持久觀察優化,方能配置適合自己系統的最佳JVM配置

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章