1. 程式人生 > >JVM GC一次調優實戰

JVM GC一次調優實戰

CMS的Full GC採用壓縮式垃圾收集,在堆比較大的時候,如果full gc頻繁,會導致停頓,並且呼叫方阻塞、超時、甚至雪崩的情況出現,所以降低full gc的發生頻率和需要時間,非常有必要。

目標

  • 減少full gc頻率
  • 減少ygc和full gc時間

優化

配置變化

優化前

<jvm-arg>-Xmx13312m</jvm-arg>
<jvm-arg>-Xms9216m</jvm-arg>
<jvm-arg>-Xmn1024m</jvm-arg>
<jvm-arg>-XX:PermSize=512M</jvm-arg
>
<!-- 使用cms回收策略 --> <jvm-arg>-XX:+UseParNewGC</jvm-arg> <jvm-arg>-XX:+UseConcMarkSweepGC</jvm-arg> <!-- 列印gc日誌 --> <jvm-arg>-XX:+PrintGCDetails</jvm-arg> <jvm-arg>-XX:+PrintGCDateStamps</jvm-arg> <jvm-arg>-XX:+PrintHeapAtGC</jvm-arg
>
<jvm-arg>-Xloggc:log/gc.log</jvm-arg>

優化後:

<jvm-arg>-Xmx13312m</jvm-arg>
<jvm-arg>-Xms13312m</jvm-arg>
<jvm-arg>-Xmn5120m</jvm-arg>
<jvm-arg>-XX:PermSize=512M</jvm-arg>
<jvm-arg>-XX:+UseParNewGC</jvm-arg>
<jvm-arg>-XX:+UseConcMarkSweepGC</jvm-arg
>
<!-- 每次full gc之後,進行壓縮 --> <jvm-arg>-XX:CMSFullGCsBeforeCompaction=0</jvm-arg> <!-- 老年代佔用75%進行full gc --> <jvm-arg>-XX:CMSInitiatingOccupancyFraction=75</jvm-arg> <jvm-arg>-XX:CMSMaxAbortablePrecleanTime=30000</jvm-arg> <jvm-arg>-XX:SurvivorRatio=6</jvm-arg> <jvm-arg>-XX:+PrintGCDetails</jvm-arg> <jvm-arg>-XX:+PrintGCDateStamps</jvm-arg> <jvm-arg>-XX:+PrintHeapAtGC</jvm-arg> <jvm-arg>-Xloggc:log/gc.log</jvm-arg>

第一次優化

將Xmx和Xms設定為一樣大小,調大Xmn

原因

  • 將Xmx和Xms設定為一樣大小,沒有必要達到Xms後,再申請Xmx

調整以下引數

<jvm-arg>-Xmx13312m</jvm-arg>
<jvm-arg>-Xms13312m</jvm-arg>
<jvm-arg>-Xmn4096m</jvm-arg>

效果 ygc由每分鐘40次,降低為10次上下 fgc時間,由之前的100ms升為300ms

第二次優化

時間一長,發現單次full gc時間太長,有時候長達2s,日誌中發現pre clean沒有結束,就進行了remark導致的。

 CMS: abort preclean due to time 2016-06-13T08:58:07.672+0800: 63803.570: [CMS-concurrent-abortable-preclean: 5.190/5.211 secs] [Times: user=12.15 sys=1.38, real=5.21 secs] 
2016-06-13T08:58:07.677+0800: 63803.575: [GC[YG occupancy: 2652667 K (3774912 K)]63803.576: [Rescan (parallel) , 1.9969650 secs]63805.573: [weak refs processing, 0.0280880 secs] [1 CMS-remark: 7082120K(9437184K)] 9734787K(13212096K), 2.
0288350 secs] [Times: user=25.39 sys=0.11, real=2.03 secs]

pre clean用於保證remark的順利進行,如果pre clean階段沒有結束,就remark,會導致remark階段延長,pre clean預設是5s,延長至30s。 調整以下引數:

 -XX:CMSMaxAbortablePrecleanTime=30000

效果 優化後,日發gc日誌中沒有abort preclean的現象發生了。

第三次優化

前兩次優化已經見到效果了,但是full gc還是比較多,且持續時間比較長,增加配置,列印物件年齡:

-XX:+PrintTenuringDistribution

因為通過ygc的物件進入老年代,是按照年齡計算的,這個年齡預設是15,但是是動態調整的,所以加這個引數,再觀察一下。 檢視日誌可以看出,物件動態調整年齡是4,太低了,物件才4歲,就進入老年代了。

2016-06-14T19:51:31.639+0800: 770.958: [GC 770.959: [ParNew
Desired survivor size 214728704 bytes, new threshold 4 (max 4)
- age   1:   27368432 bytes,   27368432 total
- age   2:   12108344 bytes,   39476776 total
- age   3:   11933416 bytes,   51410192 total
- age   4:    5568312 bytes,   56978504 total

預設配置的15,怎麼才4就進入老年代了,原來jvm是動態物件年齡判定的。

為了能更好地適應不同程式的記憶體狀況,虛擬機器並不總是要求物件的年齡必須達到Max Tenuring Threshold才能晉升老年代

如果在Survivor空間中相同年齡所有物件大小的總和大於Survivor空間的一半,年齡大於或等於該年齡的物件就可以直接進入老年代,無須等到Max Tenuring Threshold中要求的年齡。

既然取決於survivor的大小,調大survivor

修改配置:

-Xmn5120m
-XX:SurvivorRatio=6

調整後,age已經到15了。

2016-06-15T10:11:28.921+0800: 631.926: [GC 631.927: [ParNew
Desired survivor size 335544320 bytes, new threshold 15 (max 15)
- age   1:   44556600 bytes,   44556600 total
- age   2:   41122176 bytes,   85678776 total
- age   3:   14339240 bytes,  100018016 total
- age   4:   19359008 bytes,  119377024 total
- age   5:   13662592 bytes,  133039616 total
- age   6:   21144880 bytes,  154184496 total
- age   7:   17551328 bytes,  171735824 total
- age   8:    5390312 bytes,  177126136 total
- age   9:    8580176 bytes,  185706312 total
- age  10:    7921328 bytes,  193627640 total
- age  11:   17954784 bytes,  211582424 total
- age  12:    6197064 bytes,  217779488 total
- age  13:    7211632 bytes,  224991120 total
- age  14:   10837872 bytes,  235828992 total
- age  15:   10255800 bytes,  246084792 total
: 4236533K->288272K(4587520K), 0.0551150 secs] 4916941K->973217K(12976128K), 0.0557070 secs] [Times: user=0.80 sys=0.01, real=0.06 secs] 
Heap after GC invocations=68 (full 1):

效果

  • full gc由高峰期平均10分鐘一次,減少到平均1小時一次
  • ygc 由高峰期平均每分鐘40次,減少為平均每分鐘8次
  • ygc由高峰期耗時由1.5s,減少為平均500ms
  • 非高峰期,幾乎沒有full gc
  • full gc高峰期耗時有所增長,由原來的不到100ms,增長為400ms,調整堆大小了嘛

輸入圖片說明

參考資料

相關推薦

JVM GC調實戰

CMS的Full GC採用壓縮式垃圾收集,在堆比較大的時候,如果full gc頻繁,會導致停頓,並且呼叫方阻塞、超時、甚至雪崩的情況出現,所以降低full gc的發生頻率和需要時間,非常有必要。 目標 減少full gc頻率減少ygc和full gc時間 優化 配置變化 優化前 <jvm-ar

JVM GC演算法以及調

jvm的垃圾回收器是jvm的重要組成部分。GC負責著整個jvm執行時堆中物件的回收,保證jvm的效能。由於Java執行GC垃圾回收時會阻塞其他所有的執行緒,這樣是對使用者極不友好的,即對GC的優化重點是降低阻塞的時間,對GC的調優也就是對jvm的效能調優的重點。

JVM 性能調實戰之:系統性能瓶頸的尋找過程

大量 調用棧 怎麽 鎖定 穩定 verbose 註意 代碼層次 一行 前言: 玩過性能優化的朋友都清楚,性能優化的關鍵並不在於怎麽進行優化,而在於怎麽找到當前系統的性能瓶頸。性能優化分為好幾個層次,比如系統層次、算法層次、代碼層次…JVM 的性能優化被認為是底層優化,門檻較

JVM 效能調實戰之:系統性能瓶頸的尋找過程

玩過效能優化的朋友都清楚,效能優化的關鍵並不在於怎麼進行優化,而在於怎麼找到當前系統的效能瓶頸。效能優化分為好幾個層次,比如系統層次、演算法層次、程式碼層次...JVM 的效能優化被認為是底層優化,門檻較高,精通這種技能的人比較少。筆者呆過幾家技術力量不算弱的公司,每個公司內

JVM調實戰

早上檢視低峰期gc情況,發現昨晚上fgc有274次,感覺有些不正常,開始查詢原因 [[email protected]order-binlog-data002 spring-boot]$ sudo jstat -gc 20028 4000 10

JVM調實戰-理論篇》

logic nor 器) 官方 虛擬內存 1.3 三個月 最優化 all 1 理論篇1.1 多功能養魚塘-JVM內存大魚塘O(可分配內存): JVM可以調度使用的總的內存數,這個數量受操作系統進程尋址範圍、系統虛擬內存總數、系統物理內存總數、其他系統運行所占用的內存資源

ifeve.com 南方《JVM 性能調實戰之:使用阿裏開源工具 TProfiler 在海量業務代碼中精確定位性能代碼》

oca ive java tla inline .net lin 原因 調優 https://blog.csdn.net/defonds/article/details/52598018 多次拉取 JStack,發現很多線程處於這個狀態: at jrockit/vm/

ifeve.com 南方《JVM 效能調實戰之:使用阿里開源工具 TProfiler 在海量業務程式碼中精確定位效能程式碼》

https://blog.csdn.net/defonds/article/details/52598018 多次拉取 JStack,發現很多執行緒處於這個狀態:    at jrockit/vm/Allocator.getNewTla(JJ)V(Native Method) 

JVM 效能調實戰之 使用阿里開源工具 TProfiler 在海量業務程式碼中精確定位效能程式碼

                本文是《JVM 效能調優實戰之:一次系統性能瓶頸的尋找過程》 的後續篇,該篇介紹瞭如何使用 JDK 自身提供的工具進行 JVM 調優將 TPS 由 2.5 提升到 20 (提升了 7 倍),並準確定位系統瓶頸:我們應用裡靜態物件不是太多、有大量的業務執行緒在頻繁建立一些生命週期

46張PPT講述JVM體系結構、GC演算法和調

本PPT從JVM體系結構概述、GC演算法、Hotspot記憶體管理、Hotspot垃圾回收器、調優和監控工具六大方面進行講述。(內嵌iframe,建議使用電腦瀏覽) 好東西當然要分享,PPT已上傳可供下載(點此下載),另外良心推薦閱讀《深入理解Java虛擬機器JVM高階特性與最佳實踐.pdf》(點此下載)。

深入理解JVM——JVM效能調實戰

如何在高效能伺服器上進行JVM調優? 為了充分利用高效能伺服器的硬體資源,有兩種JVM調優方案,它們都有各自的優缺點,需要根據具體的情況進行選擇。   採用64位作業系統,併為JVM分配大記憶體 我們知道,如果JVM中堆記憶體太小,那麼就會頻繁地發生垃圾回收

jvm調實戰,定位效能瓶頸

玩過效能優化的朋友都清楚,效能優化的關鍵並不在於怎麼進行優化,而在於怎麼找到當前系統的效能瓶頸。效能優化分為好幾個層次,比如系統層次、演算法層次、程式碼層次…JVM 的效能優化被認為是底層優化,門檻較高,精通這種技能的人比較少。筆者呆過幾家技術力量不算弱的公司,每個公司內部真

7. GC 調(實戰篇)

本章介紹導致GC效能問題的典型情況。相關示例都來源於生產環境, 為演示需要做了一定長度的精簡。 說明: Allocation Rate, 翻譯為分配速率, 而不是分配率; 因為不是百分比,而是單位時間內分配的量; 同理, Promotion

GC調實戰

1.怎麼調優          調優的一般步驟:①首先收集gc日誌,②分析日誌中的關鍵效能指標,③分析GC原因,調優JVM引數。          衡量GC的兩個指標:①吞吐量 ②響應時間。理想情況下是高吞吐量,低響應時間,但現實往往兩個引數是相悖的。         

筆記:深入理解JVM 第5章 調案例分析與實戰

1、每天15萬 PV 的線上文件型別網站 環境:4 CPU,16GB 記憶體, 64位 CentOS 5.4 問題:網站失去響應 原先JVM配置:JDK1.5,  -Xmx12G  -Xms12G 解決過程:發現問題來自GC停頓(12G記憶體 的 Full GC 需要12秒

spark2.x-jvm調實戰(以tomcat訪問日誌分析為例)

背景 如果在持久化RDD的時候,持久化了大量的資料,那麼Java虛擬機器的垃圾回收就可能成為一個性能瓶頸。因為Java虛擬機器會定期進行垃圾回收,此時就會追蹤所有的java物件,並且在垃圾回收時,找到那些已經不在使用的物件,然後清理舊的物件,來給新的物件騰出記

JVM效能調監控工具專題JVM自帶效能調工具

前提概要:  JDK本身提供了很多方便的JVM效能調優監控工具,除了整合式的VisualVM和jConsole外,還有jps、jstack、jmap、jhat、jstat、hprof等小巧的工具,每一種工具都有其自身的特點,使用者可以根據你需要檢測的應用或者程式片段的狀況,適

深入理解JVM(六)——JVM效能調實戰

如何在高效能伺服器上進行JVM調優? 為了充分利用高效能伺服器的硬體資源,有兩種JVM調優方案,它們都有各自的優缺點,需要根據具體的情況進行選擇。 1. 採用64位作業系統,併為JVM分配大記憶體 我們知道,如果JVM中堆記憶體太小,那麼就會頻繁地

文讀懂Java GC原理和調

概述 本文介紹GC基礎原理和理論,GC調優方法思路和方法,基於Hotspot jdk1.8,學習之後將瞭解如何對生產系統出現的G

sql優化——left join不走索引問題

alt 卡住 image sql col ima cnblogs 優化 .cn sql一執行就卡住,然後就...殺進程了 看了一下表的大小 第一反應就是加索引,然後explain看了一下走什麽索引了,結果很尷尬,三個表,只走了一個索引...一群人在那糾結為毛走不了索引。