Java服務GC參數調優案例

這段時間在整理jvm系列的文章,無意中發現本文,作者思路清晰通過步步分析最終解決問題。我個人特別喜歡這種實戰類的內容,經原作者的授權同意,將文章分享于此。原文鏈接:Java服務GC參數調優案例,下面為轉載此文的內容,備注部分為本人添加,主要起到說明的作用。

背景以及遇到的問題
我們的Java HTTP服務屬于OLTP類型,對成功率和響應時間的要求比較高,在生產環境中出現偶現的成功率突然下降然后又自動恢復的情況,如圖所示:

JVM和GC相關的參數如下:

-Xmx22528m
-Xms22528m
-XX:NewRatio=2
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled
1
2
3
4
5
6
總結來說,由于服務中大量使用了Cache,所以堆大小開到了22G。GC算法使用CMS(UseConcMarkSweepGC),開啟了降低標記停頓(CMSParallelRemarkEnabled),設置年輕代為并行收集(UseParNewGC),年輕代和老年代的比例為1:2 (NewRatio=2).

JVM GC日志相關的參數如下:

-Xloggc:/data/gc.log
-XX:GCLogFileSize=10M
-XX:NumberOfGCLogFiles=10
-XX:+UseGCLogFileRotation
-XX:+PrintGCDateStamps
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
-XX:+DisableExplicitGC
-verbose:gc
1
2
3
4
5
6
7
8
9
問題解決過程
排除應用程序的內存使用問題
首先使用jmap查看內存使用情況:

jmap -histo:live PID
1
這個命令把程序中當前的對象按照個數和占用的空間排序以后打印出來。這里沒有發現使用異常的對象。

排除Cache內容過多的問題
如果Cache內容過多也會導致JVM老年代容易被用滿導致頻繁GC,因此調出GC日志進行查看,發現每次GC以后內存使用一般是從20G降低到5G左右,因此常駐內存的Cache不是導致GC長時間卡頓的根本原因。對于GC LOG的查看有多種方式,使用VisualVM比較直觀,需要使用VisualGC:

從圖中我們可以看到伊甸園和老年代的空間分配,由于整體內存是20G,設置 -XX:NewRatio=2 因此老年代是14G,伊甸園+S0+S1=7G

調整GC時間點(成功率抖動問題加重)
如果GC需要處理的內存量比較大,執行的時間也就比較長,STW (Stop the World)時間也就更長。按照這個思路調整CMS啟動的時間點,希望提早GC,也就是讓GC變得更加頻繁但是期望每次執行的時間較少。添加了下面這兩個參數:

-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=50
1
2
意思是說在Old區使用了50%的時候觸發GC。實驗后發現GC的頻率有所增加,但是每次GC造成的陳功率降低現象并沒有減弱,因此棄用這兩個參數。

調整對象在年輕代內存中駐留的時間(效果不明顯)
如果能夠降低老年代GC的頻率也可以達到降低GC影響的目的,因此嘗試讓對象在年輕代內存中進行更長時間的駐留,提升這些對象在年輕代GC時候被銷毀的概率。使用參數-XX:MaxTenuringThreshold=31調整以后收效不明顯。

備注:?
1、MaxTenuringThreshold 在1.5.0_05之前最大值可以設置為31 ,1.5.0_06以后最大值可以設置為15,超過15會被認為無限大。參考:Never set GC parameter -XX:MaxTenuringThreshold greater than 15?
2、提升年輕代GC被銷毀的概率,只是調整這個參數效果不大,第二次age的值會重新計算,參考:說說MaxTenuringThreshold這個參數

CMS-Remark之前強制進行年輕代的GC
首先補充一下CMS的相關知識,在CMS整個過程中有兩個步驟是STW的,如圖紅色部分:

CMS并非沒有暫停,而是用兩次短暫停來替代串行標記整理算法的長暫停,它的收集周期是這樣:

1、初始標記(CMS-initial-mark),從root對象開始標記存活的對象
2、并發標記(CMS-concurrent-mark)
3、重新標記(CMS-remark),暫停所有應用程序線程,重新標記并發標記階段遺漏的對象(在并發標記階段結束后對象狀態的更新導致)
4、并發清除(CMS-concurrent-sweep)
5、并發重設狀態等待下次CMS的觸發(CMS-concurrent-reset)。
通過GC日志和成功率下降的時間點進行比對發現并不是每一次老年代GC都會導致成功率的下降,但是從中發現了一個規律:

前兩次GC CMS-Remark過程在4s左右造成了成功率的下降,但是第三次GC并沒有對成功率造成明顯的影響,CMS-Remark只有0.18s。Java HTTP 服務是通過Nginx進行反向代理的,nginx設置的超時時間是3s,所以如果GC卡頓在3s以內就不會對成功率造成太大的影響。

從GC日志中又發現一個信息:

在文檔和相關資料中沒有找到藍色部分的含義,猜測是remark處理的內存量,處理的越多就越慢。添加下面兩個參數強制在remark階段和FULL GC階段之前先在進行一次年輕代的GC,這樣需要進行處理的內存量就不會太多。

備注:?
1、藍色部分的含義:remark標記需要清理對象的容量。關于如何分析CMS日志,可以參考這篇文章:了解 CMS 垃圾回收日志?
2、FULL GC階段之前先在進行一次年輕代的GC的意義是:Yong區對象引用了Old區的對象,如果在Old區進行清理之前不進行Yong區清理,就會導致Old區被yong區引用的對象無法釋放。可以參考這篇文章:假笨說-又抓了一個導致頻繁GC的鬼–數組動態擴容

-XX:+ScavengeBeforeFullGC?
-XX:+CMSScavengeBeforeRemark
1
2
調優以后效果很明顯,下面是兩臺配置完全相同的服務器在同一時間段的成功率和響應時間監控圖,第一個沒有添加強制年輕代GC的參數。

?


結論
1、在CMS-remark階段需要對堆中所有的內存對象進行處理,如果在這個階段之前強制執行一次年輕代的GC會大量減少remark需要處理的內存數量,進而降低JVM卡頓對成功率的影響。?
2、對于Java HTTP服務,JVM的卡頓時間應該小于HTTP客戶端的調用超時時間,否則JVM卡頓會對成功率造成影響。

感謝匠心零度對文章內容進行深入的探討,備注內容屬于討論后的結果
---------------------?
作者:微笑很純潔?
來源:CSDN?
原文:https://blog.csdn.net/ityouknow/article/details/79078249?
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

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

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

相關文章

RUNOOB python 67 數組的元素互換

用來練手的Python練習題,原題鏈接:python練習實例67 題干: 輸入數組,最大的與第一個元素交換,最小的與最后一個元素交換,輸出數組 代碼如下: import numpy as nptable np.array([10,4,9,3,11,25,37,15,2,231,672,22]) #定義sw…

11.13 ethtool:查詢網卡參數

ethtool命令用于查詢或設置網卡參數。ethtool [devname][rootlinuxprobe ~]# ethtool eth0Settings for eth0:Supported ports: [ TP ]Supported link modes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full 1000baseT/Full Supported pause frame use: NoSupports au…

微信小程序、微信公眾號、H5之間相互跳轉

一、小程序和公眾號 答案是:可以相互關聯。 在微信公眾號里可以添加小程序。 圖片有點小,我把文字打出來吧: 可關聯已有的小程序或快速創建小程序。已關聯的小程序可被使用在自定義菜單和模版消息等場景中。 公眾號可關聯同主體的10個小程…

數組元素前移后移 RUNOOB python練習題 68

用來練手的python練習題,原題鏈接: python練習實例68 題干: 有 n 個整數,使其前面各數順序向后移 m 個位置,最后 m 個數變成最前面的 m 個數 代碼如下: import numpy as np # 構造一個儲存了n個整數的numpy數組 def numbers_input(n):a n…

LRU緩存簡單實現

緩存接口定義 /*** 緩存接口* * author zhi**/ public interface ICache<K, V> {/*** 添加緩存數據* * param key* param value*/void put(K key, V value);/*** 獲取緩存數據* * param key* return*/V get(K key);/*** 刪除緩存數據* * param key* return*/V remove(K k…

Mac Eclipse安裝lombok

Lombok是一個可以通過注解的形式可以幫助消除一些必須但是顯得很臃腫的Java代碼的工具&#xff0c;通過使用對應的注解&#xff0c;可以在進行編譯源碼的時候生成對應的方法&#xff0c;比如類屬性的get/set/toString()/類的構造方法等. 下面記錄一下在Mac Eclipse是如何安裝Lo…

tf.reduce_sum()方法深度解析

首先看一下reduce_sum及其參數的注釋 : def tf.reduce_sum(input_tensor, axisNone, keepdimsFalse, nameNone) Computes the sum of elements across dimensions of a tensor. Reduces input_tensor along the dimensions given in axis. Unless keepdims is true, the rank o…

主成分分析(PCA)原理詳解_轉載

一、PCA簡介 1. 相關背景 在許多領域的研究與應用中&#xff0c;往往需要對反映事物的多個變量進行大量的觀測&#xff0c;收集大量數據以便進行分析尋找規律。多變量大樣本無疑會為研究和應用提供了豐富的信息&#xff0c;但也在一定程度上增加了數據采集的工作量&#xff0c;…

Mac cnpm裝包時提示Error: EACCES: permission denied解決辦法

Cnpm裝包時提示Error: EACCES: permission denied解決辦法 2018年03月04日 09:31:51 miniminixu 閱讀數&#xff1a;1598 版權聲明&#xff1a;本文為博主原創文章&#xff0c;未經博主允許不得轉載。 https://blog.csdn.net/miniminixu/article/details/79434609 只需在cnpm …

特征點檢測 FAST算法及代碼詳解

本文著重介紹了用于圖像特征點檢測的算法&#xff0c;FAST算法&#xff0c;以及使用matlab的實現。 FAST算法是一種拐點檢測算法&#xff0c;其主要應用于提取圖像中的特征點&#xff0c;在動態成像的一系列圖像中追蹤定位對象。眾所周知&#xff0c;我們生活的世界是動態化的…

Python Email發送,通知業務完成

Email 發送 #!/usr/bin/python # -*- coding: UTF-8 -*- import base64 import smtplib from email.mime.text import MIMEText from email.header import Header from email.utils import formataddrdef crypt(source, key):from itertools import cycleresulttempcycle(key)f…

基于SpringCloud的分布式事務框架(LCN)

框架特點 支持各種基于spring的db框架 兼容springcloud、dubbo 使用簡單&#xff0c;代碼完全開源 基于切面的強一致性事務框架 高可用&#xff0c;模塊可以依賴dubbo或springcloud的集群方式做集群化&#xff0c;TxManager也可以做集群化 使用示例 分布式事務發起方&#xf…

一文看懂計算機神經網絡與梯度下降

1. 計算機神經網絡與神經元 要理解神經網絡中的梯度下降算法&#xff0c;首先我們必須清楚神經元的定義。如下圖所示&#xff0c;每一個神經元可以由關系式yf(∑i1nwixib)y f(\sum_{i1}^nw_ix_i b)yf(∑i1n?wi?xi?b)來描述&#xff0c;其中X[x1,x2,...,xn]X [x_1,x_2,..…

vs2015web項目無法加載64位c++的dll,提示試圖加載不正確的格式

vs2015無法加載64位c的dll&#xff0c;提示試圖加載不正確的格式&#xff01; 開始用winform引用64位的c的dll&#xff0c;在項目的屬性設置生成里面選擇any cpu或者x64都可以成功! 但在web項目和接口里面運行就提示試圖加載不正確的格式&#xff0c;想辦法找了一天也沒處理掉&…

使用Rancher搭建K8S測試環境

環境準備&#xff08;4臺主機&#xff0c;Ubuntu16.04Docker1.12.6 SSH&#xff09;&#xff1a; rancher1 192.168.3.160 只做管理節點 node1 192.168.3.161 K8S的節點1 node2 192.168.3.162 K8S的節點2 node3 192.168.3.163 K8S的節點3 此時如…

Anaconda安裝tensorflow報錯問題解決方法

最近脫離了googlecolab想使用本地的anaconda進行機器學習課題的演練&#xff0c;在安裝tensorflow時報錯 : UnsatisfiableError: The following specifications were found。下面給出解決方法。 發現實際原因是由于anaconda的python環境&#xff0c;當前版本的tensorflow只能適…

5.07—018—周二

今日所學內容 一、模塊 二、遞歸刪除的思路 三、案例&#xff1a;跨文件夾移動文件 四、案例 遞歸遍歷打印目標路徑中所有的txt文件 五、項目開放周期 一、模塊 1、與時間相關的模塊 1&#xff09;time &#xff1a;時間 時間戳(timestamp)&#xff1a;time.time()  延遲線程…

機器學習模型中step與epoch,batch_size之間的關系

本文主要談談自己對step&#xff0c;epoch&#xff0c;batch_size這幾個常見參數的理解。 最近在調試模型的時候&#xff0c;發現在使用keras.optimizer.adam時&#xff0c;模型在添加了新的一層2D卷積層后難以收斂&#xff0c;在不調整初始權重矩陣的情況下&#xff0c;想通過…

yml的mybatis的sql查看

yml的mybatis的sql查看 控制臺輸出結果:

Debian 安裝 yum

sudo apt-get updatesudo apt-get install build-essentialsudo apt-get install yum轉載于:https://www.cnblogs.com/baiqian/p/10840169.html