文档章节

cms优化之晋升失败

Mr_Qi
 Mr_Qi
发布于 2017/07/25 16:30
字数 882
阅读 173
收藏 3
点赞 0
评论 2

背景

最近系统的用户使用越来越多,随之而来的情况导致系统在运行一段时间后开始出现fgc(频次大约1天2次),cms作为高响应速度的collector,一般我们会尽量避免出现remark或者尽量减低remark的时间(remark阶段会出现stop the world)

我们关注一下zabbix的内存监控图

注:系统为jdk7

如上两张图分别对应堆内存的使用和老年代的使用

从上图可以看出,基本上minor gc比较频繁(第一张的锯齿),并没有出现内存泄露(第一张图在fgc的回收下内存占用几乎不变)

那么出现一次较大的fgc的原因是什么呢?

我们参看一下当前系统的情况

小知识,cms在一次remark前后各算一次fgc

基本看出老年代使用并不高,而年轻代比较小,伊甸园去仅为209m ,幸存者区域约为26m(换句话说,一次晋升最多可能晋升26+209M)

我们看到此次晋升失败,而老年代从2.3g直接fullgc到了500m,存在1.8g的内存回收。中断时间约为2.69s

初步考虑内存分配不合理导致年轻代过小,出现多次的minor gc(minor gc的频率直接决定了对象的年龄,而年龄又决定了晋升到老年代的时机)-XX:MaxTenuringThreshold 最大为15

查看一下我们的jvm参数

 /usr/java/jdk1.7.0_80/bin/java -Djava.util.logging.config.file=/mnt/apache-tomcat-7.0.70-erp/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Xms2048m -Xmx3072m -XX:PermSize=128m -XX:MaxNewSize=256m -XX:MaxPermSize=256m -XX:ParallelGCThreads=4 -XX:+UseConcMarkSweepGC -Xloggc:/mnt/apache-tomcat-7.0.70-erp/logs/gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+DisableExplicitGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/mnt/apache-tomcat-7.0.70-erp -Djava.endorsed.dirs=/mnt/apache-tomcat-7.0.70-erp/endorsed -classpath /mnt/apache-tomcat-7.0.70-erp/bin/bootstrap.jar:/mnt/apache-tomcat-7.0.70-erp/bin/tomcat-juli.jar -Dcatalina.base=/mnt/apache-tomcat-7.0.70-erp -Dcatalina.home=/mnt/apache-tomcat-7.0.70-erp -Djava.io.tmpdir=/mnt/apache-tomcat-7.0.70-erp/temp org.apache.catalina.startup.Bootstrap start

WTF 居然设置了-XX:MaxNewSize为256m,那么默认的surviorRatio为8 也就是 s0=25.6m s1=25.6m eden=204.8m 

为了减低cms在gc时remark时间 考虑调大年轻代,这样对象分配时在年轻代,由于年轻代足够大,不会频繁发生minor gc,这样对象的年龄不会变大的太快。所以需要设置合理的newRatio。

export CATALINA_OPTS="$CATALINA_OPTS -Xms2048m -Xmx3072m -XX:PermSize=128m -XX:NewRatio=3 -XX:MaxPermSize=256m -XX:CMSInitiatingOccupancyFraction=72 -XX:ParallelGCThreads=4 -XX:+UseConcMarkSweepGC -Xloggc:/mnt/apache-tomcat-7.0.70-erp/logs/gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+DisableExplicitGC  -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/mnt/apache-tomcat-7.0.70-erp"

将年轻代设置为512m~768m

同时加上-XX:CMSInitiatingOccupancyFraction

该参数表示在老年代达到72%时将强行发生fgc,优先回收内存,以防止出现年轻代晋升失败的情况。

年轻代晋升失败条件如下(不考虑内存碎片):

幸存者+伊甸园区<老年代剩余

采用默认比例 surviorRatio 为8 

此处newRatio为3

公式为

(1+surviorRatio)/(2+surviorRatio)*new <=old*(1-CMSInitiatingOccupancyFraction/100)

得出CMSInitiatingOccupancyFraction约为70 此处使用72(经验值)

原先设置年轻代大小应该是老的jvm参数,当修改了xmx之后没有更新该值,导致年轻代过小

因此此处考虑使用ratio

以观后效

经过改造 目前zabbix的内存使用图如下(最后一天)

基本上可以在老年代达到一定容量时就回收掉,同时stw时间明显降低

原来统计从运行3天暂停8s降低 到运行1天 暂停0.082s

younggc的频率也有所下降,时间也缩短。

© 著作权归作者所有

共有 人打赏支持
Mr_Qi
粉丝 252
博文 298
码字总数 312931
作品 0
南京
程序员
加载中

评论(2)

Mr_Qi
Mr_Qi

引用来自“huihrt”的评论

大佬,在南京的哪一个公司啊

回复@huihrt : 江苏爱福路
h
huihrt
大佬,在南京的哪一个公司啊
cms优化之晋升失败

背景 最近系统的用户使用越来越多,随之而来的情况导致系统在运行一段时间后开始出现fgc(频次大约1天2次),cms作为高响应速度的collector,一般我们会尽量避免出现remark或者尽量减低remar...

波波维奇 ⋅ 2017/11/30 ⋅ 0

了解 CMS 垃圾回收日志

在CMS GC 时,使用参数-XX:+PrintGCDetails 和 -XX:+PrintGCTimeStamps 会输出很多日志信息,了解这些信息可以帮我们更好的调整参数,以获得更高的性能。 我们来看下在JDK1.4.2_10 中CMS GC日...

serenity ⋅ 2015/06/15 ⋅ 0

《深入理解Java虚拟机》——垃圾收集器参数总结

JDK1.6垃圾收集相关参数 参数 描述 UseSerialGC 虚拟机运行在Client模式下的默认值,打开此开关后,使用Serial+Serial Old的收集器组合进行内存回收 UseParNewGC 打开此开关后,使用ParNew+...

戴的天 ⋅ 2014/08/18 ⋅ 0

GC日志分析 & GC常用参数

1:GC日志分析 最前面的数字 33.125 和 100.667 代表了GC的执行时间,是从Java虚拟机启动以来经过的秒数。 “GC”和“Full GC”说明了这次垃圾收集的停顿类型。如果有“Full”则说明 GC 发生...

ZHAOBEN ⋅ 2016/04/26 ⋅ 0

《Java性能优化权威指南》读书笔记(二)

JVM性能调优入门 ----- 基本原则 Minor GC回收原则,尽可能多的收集垃圾 GC内存最大化原则,堆越大越好 GC调优3选2原则,吞吐量、延迟、内存占用 关注吞吐量和延迟的Java应用程序,都应该将-...

selfless ⋅ 2016/07/03 ⋅ 3

jvm诊断与优化(6)

STW(stop-the-world):当GC触发时为了正常且高效的执行,大部分情况下,会要求系统进入一个停顿的状态(终止所有的应用线程),保证应用不再产生新的垃圾及在某一瞬间的一致性,也更好的标记对...

Canaan_ ⋅ 2016/04/25 ⋅ 0

Java虚拟机学习 - 垃圾收集器

HotSpot JVM收集器 上面有7中收集器,分为两块,上面为新生代收集器,下面是老年代收集器。如果两个收集器之间存在连线,就说明它们可以搭配使用。 Serial(串行GC)收集器 Serial收集器是一个...

星逝流 ⋅ 2016/02/17 ⋅ 0

Java虚拟机学习 - 垃圾收集器

HotSpot JVM收集器 上面有7中收集器,分为两块,上面为新生代收集器,下面是老年代收集器。如果两个收集器之间存在连线,就说明它们可以搭配使用。 Serial(串行GC)收集器 Serial收集器是一个...

星逝流 ⋅ 2016/02/17 ⋅ 2

JVM内存分配与垃圾回收浅析

想做architect,就必须对JVM的性能有所了解。JVM的内存管理是性能的一大瓶颈。JVM的性能调优,必须建立在对内存管理策略理解的基础之上。内容太多,简单的写写。 Agenda是: JVM内存划分 ->垃...

xpbug ⋅ 2012/04/24 ⋅ 4

部分JVM参数解释

从大神手里拿过来的JVM调优参数,仅仅是把每个参数的含义查询了一下,越是查询越是感觉得到,小用户量的产品优化无从谈起,用户量起来了一切就要从细节入手慢慢优化。知识还需要继续深化,自...

iHenn ⋅ 2014/04/29 ⋅ 1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

对于程序员的招聘问题,作为软件人的一些吐槽和建议

作为软件人,找工作有时候似乎挺苦逼的。 说真的,让我去掉前面这句中“似乎”二字吧。就是苦逼!很多人都曾抱怨处在招聘的一方很糟糕——我们没有任何可靠的方式来甄别会写代码并且写得好的...

老道士 ⋅ 11分钟前 ⋅ 0

HDFS原理学习

一、概述 1、 Hadoop整合了众多的文件系统,首先提供了一个高层的文件系统抽象org.apache.hadoop.fs.FileSystem。然后有各个文件系统的实现类。 2、Hadoop是JAVA编写的,不同文件系统之间的交...

cjxcloud ⋅ 15分钟前 ⋅ 0

Linux下MySQL表名不区分大小写的设置方法(抄袭别人的)

Linux下MySQL表名不区分大小写的设置方法 MySQL表名不区分大小写的设置方法 在用centox安装mysql后,把项目的数据库移植了过去,发现一些表的数据查不到,排查了一下问题,最后发现是表名的大...

随风而浮沉 ⋅ 20分钟前 ⋅ 0

ubuntu下安装宋体simsun

sudo cp simsun.ttc /usr/share/fonts cd /usr/share/fonts sudo chmod 644 simsun.ttc 更新字体缓存: 代码: sudo mkfontscale 代码: sudo mkfontdir 代码: sudo fc-cache -fsv 安装chrome扩......

wangxuwei ⋅ 22分钟前 ⋅ 0

利用 ssh 传输文件

Linux 下一般可以用 scp 命令通过 ssh 传送文件: #把服务器上的 /home/user/a.txt 发送到本机的 /var/www/local_dir 目录下scp username@servername:/home/user/a.txt /var/www/local_dir...

大灰狼时间 ⋅ 32分钟前 ⋅ 0

web3j教程:android和java程序员如何使用web3j开发区块链以太坊

如何使用web3j为Java应用或Android App增加以太坊区块链支持,本教程内容即涉及以太坊中的核心概念,例如账户管理包括账户的创建、钱包创建、交易转账,交易与状态、智能合约开发与交互、过滤...

智能合约 ⋅ 54分钟前 ⋅ 0

web3j开发java或android以太坊智能合约快速入门

web3j简介 web3j是一个轻量级、高度模块化、响应式、类型安全的Java和Android类库提供丰富API,用于处理以太坊智能合约及与以太坊网络上的客户端(节点)进行集成。 可以通过它进行以太坊区块链...

笔阁 ⋅ 56分钟前 ⋅ 0

一起读书《深入浅出nodejs》-异步I/O

异步I/O “异步”这个名词其实很早就诞生了,但它大规模流行却是在Web 2.0浪潮中,它伴随着AJAX的第一个A(Asynchronous)席卷了Web。 为什么要异步I/O 关于异步I/O为何在Node里如此重要,这与...

小草先森 ⋅ 59分钟前 ⋅ 0

JVM各种问题

1、如果启动什么都不设,会怎样? 先来看一个命令 [root@localhost bin]# java -XX:+PrintCommandLineFlags -version -XX:InitialHeapSize=29899008 -XX:MaxHeapSize=478384128 -XX:+PrintCo......

算法之名 ⋅ 今天 ⋅ 0

SAS笔记-宏2

宏是一种文本,一般来说其编译是在程序执行之前。 宏变量的创建 %let语句 %let macro_variables = text; %let是常见的宏变量建立方式,其编译就在执行前。如下例中,想要宏变量test等于数据集...

tonorth123 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部