jvm调优

2019-06-04  本文已影响0人  戈羽殇雪

线上环境使用的jdk版本为jdk1.7.0_80,tomcat版本为apache-tomcat-7.0.68
都是比较老的。在线上环境中,应用运行差不多10天之后,就把1台4c 8G的虚拟机
的内存耗尽了,看了几天的内容,想尝试着将本地应用进行优化。
原始的参数是这样的:

JAVA_OPTS="-server \
-Xms4g \
-Xmx4g \
-Xmn2g \
-Xss256K \
-XX:MaxDirectMemorySize=4096m \
-XX:PermSize=256m \
-XX:MaxPermSize=256m \
-XX:+UseParNewGC \
-XX:MaxTenuringThreshold=2 \
-XX:SurvivorRatio=8 \
-XX:ParallelGCThreads=24 \
-XX:+UnlockDiagnosticVMOptions \
-XX:ParGCCardsPerStrideChunk=32768 \
-XX:+UseConcMarkSweepGC \
-XX:-CMSParallelRemarkEnabled \
-XX:+ParallelRefProcEnabled \
-XX:+CMSClassUnloadingEnabled \
-XX:CMSInitiatingOccupancyFraction=80 \
-XX:+UseCMSInitiatingOccupancyOnly \
-XX:+ExplicitGCInvokesConcurrent \
-Dsun.rmi.dgc.client.gcInterval=14400000 \
-Dsun.rmi.dgc.server.gcInterval=14400000 \
-XX:+AlwaysPreTouch \
-XX:+PrintGCDetails \
-XX:+PrintGCTimeStamps \
-XX:+PrintGCDateStamps \
-XX:+PrintTenuringDistribution \
-XX:+PrintGCApplicationStoppedTime \
-XX:-OmitStackTraceInFastThrow \
-Xloggc:/letv/logs/tomcat/gc.log \
-Dtomcat.log=/letv/logs/tomcat \
-Djava.net.preferIPv4Stack=true"

-Xms:初始堆大小 8g
-Xmx:最大堆大小 8g
-Xmn:年轻代大小 4g,大小为堆空间的1半
-XX:PermSize=256m
-XX:SurvivorRatio=8 ,代表两个Survivor:Eden=2:8,每个Survivor占用空间为1/10(2*Survivor+Eden=Xmn),为400m
-XX:MaxTenuringThreshold=2,设置垃圾最大年龄,年轻代对象最多经过2次gc晋升到老年代,最大值为15,但并非需要15次才
进入老年代,当Survivor空间不足时,便会提前进入老年代,若此值为0,年轻代对象不通过Survivor就会进入年老代
-XX:+UseParNewGC 设置年轻代为多线程收集。可与CMS收集同时使用。在serial基础上实现的多线程收集器。
还有另外的一种方式UseParallelGC:选择垃圾收集器为并行收集器。此配置仅对年轻代有效。可以同时并行多个垃圾收集线程,但此时用户线程必须停止。
-UseParallelGC 关注吞吐量
-UseParNewGC 关注响应时间
-XX:ParallelGCThreads=24 这个一般是根据CPU的核数来确定的,24对现在的机器来说有点过大:

ParallelGCThreads = (ncpus <= 8) ? ncpus : (8 + ((ncpus - 8) * 5) / 8);

-XX:CMSInitiatingOccupancyFraction=80,老年代GC触发时其空间占用率
80是指百分比,老年代填充到80%时,开始对老年代执行老年代并发垃圾回收(CMS)
(Xmx-Xmn)*(100-CMSInitiatingOccupancyFraction)/100>=Xmn 满足此公式,垃圾回收时不会出现promotion failed

根据上面的参数对生产环境进行调整:

JAVA_OPTS="-server \
-Xms4g \
-Xmx4g \
-Xmn500m \
-Xss256K \
-XX:MaxDirectMemorySize=4096m \
-XX:PermSize=500m \
-XX:MaxPermSize=500m \
-XX:+UseParNewGC \
-XX:SurvivorRatio=1 \
-XX:ParallelGCThreads=4 \
-XX:+UnlockDiagnosticVMOptions \
-XX:ParGCCardsPerStrideChunk=32768 \
-XX:+UseConcMarkSweepGC \
-XX:-CMSParallelRemarkEnabled \
-XX:+ParallelRefProcEnabled \
-XX:+CMSClassUnloadingEnabled \
-XX:CMSInitiatingOccupancyFraction=85 \
-XX:+UseCMSInitiatingOccupancyOnly \
-XX:+ExplicitGCInvokesConcurrent \
-Dsun.rmi.dgc.client.gcInterval=14400000 \
-Dsun.rmi.dgc.server.gcInterval=14400000 \
-XX:+AlwaysPreTouch \
-XX:+PrintGCDetails \
-XX:+PrintGCTimeStamps \
-XX:+PrintGCDateStamps \
-XX:+PrintTenuringDistribution \
-XX:+PrintGCApplicationStoppedTime \
-XX:-OmitStackTraceInFastThrow \
-Xloggc:/letv/logs/tomcat/gc.log \
-Dtomcat.log=/letv/logs/tomcat \
-Djava.net.preferIPv4Stack=true"

减小年轻代大小,设置Xmn为500m,同时提高Permsize 为500m,避免伸缩带来压力,
同时为了CMS并发垃圾回收产生promotion failed,参照公式(Xmx-Xmn)*(100-CMSInitiatingOccupancyFraction)/100>=Xmn
设置:
-XX:CMSInitiatingOccupancyFraction=85
同时因为回收暂停的原因,去掉了MaxTenuringThreshold参数
同时因为cpu核数的问题,设置XX:ParallelGCThreads=4 ,gc并发线程数为4

这样设置之后cms执行频率较低,年老代和永久代上升很慢,大家可以参考下

上一篇下一篇

猜你喜欢

热点阅读