JVM 垃圾回收經驗

優化經驗:java

  1. 年輕代選擇。避免設置太小,當新生代設置太小時會致使,YGC次數更加頻繁,可能致使YGC對象直接進入年老代,若是此時年老代滿了,會容易觸發Full GC;
  2. 年老代選擇。年老代使用併發收集器,因此其大小須要當心設置,通常要考慮併發會話率和會話持續時間等一些參數,若是堆設置小了,能夠會形成內存碎片,高回收頻率以及應用暫停而使用傳統的標記清除方式;若是堆大了,則須要較長的收集時間,最優化的方案,通常須要參考併發垃圾收集信息、持久代併發收集次數、傳統GC信息、花在年輕代和年老代回收上的時間比例;
  3. Xms和Xmx設置同樣大,MaxPermSize和MinPermSize設置同樣大,這樣能夠減輕伸縮堆大小帶來的壓力;
  4. 較小堆引發的碎片問題,由於年老代的併發收集器使用標記清除算法,因此不會對堆進行壓縮.當收集器回收時,他會把相鄰的空間進行合併,這樣能夠分配給較大的對象,可是當堆空間較小時,運行一段時間之後,就會出現」碎片",若是併發收集器找不到足夠的空間,那麼併發收集器將會中止,而後使用傳統的標記,清除方式進行回收,若是出現」碎片",可能須要進行以下配置:
    -XX:+UseCMSCompactAtFullCollection // 使用併發收集器時,開啓對年老代的壓縮
    -XX:CMSFullGCsBeforeCompaction=0 // 設置多少次Full GC後,對年老代進行壓縮
  5. 使用CMS要注意初始標記和從新標記,由於這兩個階段是STW,通常在初始標記和從新標記前都會進行YGC,在從新標記前保證preclean下,保證從新標記不會太耗時。
     

優化配置:linux

-Xmx1024m
-Xms1024m     // 將Xmx和Xms設置同樣大,避免調整
-Xmn384m      // 默認爲堆的1/3,官方推薦爲堆的3/8
-XX:PermSize=128m
-XX:MaxPermSize=128m                     // 將持久代設置同樣帶,避免調整
-XX:+UseParNewGC                         // 年輕代使用並行gc
-XX:+UseConcMarkSweepGC                  // 年老代使用並行gc
-XX:CMSFullGCsBeforeCompaction=0         // 每次full gc以後,進行壓縮
-XX:CMSInitiatingOccupancyFraction=75    // 年老代佔75進行full gc
-XX:CMSMaxAbortablePrecleanTime=20000    // 延長preclean時間
-XX:SurvivorRatio=6    // 增大Survivor的大小,避免年輕代過早進入年老代
-XX:+PrintGCDetails    // 打印gc log
-XX:+PrintGCDateStamps
-XX:+PrintHeapAtGC
​​​​​​​-Xloggc:root/gc.log


優化主要借鑑垃圾回收日誌,主要查看YGC和FGC的頻率和時長,若是YGC和FGC過於頻繁多是年輕代和Survivor區太小,CMS FGC必定要注意1和4兩個兩個階段,這兩個階段是STW的,在初始標記前進行YGC和在從新標記前充分的preclean均可以提升效率。算法

Java HotSpot(TM) 64-Bit Server VM (25.111-b14) for linux-amd64 JRE (1.8.0_111-b14), built on Sep 22 2016 16:14:03 by "java_re" with gcc 4.3.0 20080428 (Red Hat 4.3.0-8)
Memory: 4k page, physical 1016272k(621800k free), swap 0k(0k free)
CommandLine flags: -XX:CMSFullGCsBeforeCompaction=0 -XX:InitialHeapSize=536870912 -XX:MaxHeapSize=536870912 -XX:MaxNewSize=209715200 -XX:MaxTenuringThreshold=6 -XX:NewSize=209715200 -XX:OldPLABSize=16 -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+UseParNewGC 
2016-10-27T18:26:59.917+0800: 4.213: [GC (CMS Initial Mark) [1 CMS-initial-mark: 0K(319488K)] 88688K(503808K), 0.0456410 secs] [Times: user=0.04 sys=0.00, real=0.04 secs] 
2016-10-27T18:26:59.967+0800: 4.262: [CMS-concurrent-mark-start]
2016-10-27T18:26:59.969+0800: 4.264: [CMS-concurrent-mark: 0.002/0.002 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2016-10-27T18:26:59.969+0800: 4.264: [CMS-concurrent-preclean-start]
2016-10-27T18:26:59.970+0800: 4.266: [CMS-concurrent-preclean: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2016-10-27T18:26:59.970+0800: 4.266: [CMS-concurrent-abortable-preclean-start]
 CMS: abort preclean due to time 2016-10-27T18:27:05.035+0800: 9.330: [CMS-concurrent-abortable-preclean: 0.122/5.064 secs] [Times: user=3.12 sys=0.13, real=5.07 secs] 
2016-10-27T18:27:05.035+0800: 9.330: [GC (CMS Final Remark) [YG occupancy: 157528 K (184320 K)]2016-10-27T18:27:05.035+0800: 9.330: [Rescan (parallel) , 0.0812074 secs]2016-10-27T18:27:05.116+0800: 9.412: [weak refs processing, 0.0000577 secs]2016-10-27T18:27:05.116+0800: 9.412: [class unloading, 0.0053644 secs]2016-10-27T18:27:05.122+0800: 9.417: [scrub symbol table, 0.0041047 secs]2016-10-27T18:27:05.126+0800: 9.421: [scrub string table, 0.0006452 secs][1 CMS-remark: 0K(319488K)] 157528K(503808K), 0.0925696 secs] [Times: user=0.09 sys=0.00, real=0.09 secs] 
2016-10-27T18:27:05.128+0800: 9.423: [CMS-concurrent-sweep-start]
2016-10-27T18:27:05.128+0800: 9.423: [CMS-concurrent-sweep: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2016-10-27T18:27:05.128+0800: 9.423: [CMS-concurrent-reset-start]
2016-10-27T18:27:05.130+0800: 9.425: [CMS-concurrent-reset: 0.002/0.002 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
相關文章
相關標籤/搜索