使用Docker容器时需要更改GC并发参数配置
最近在做统一服务优化时发现使用容器时垃圾回收偏长,而我们的服务是一个响应时间优先的应用,需要对GC进行一些调优,在对容器内Java应用进行GC时发现:(8核)如下是8核机器的GC,CMS,young gc基本在100ms左右
(8核)经发现与GC线程有关,通过指定并发GC线程数 -XX:ParallelGCThreads=8 -XX:ConcGCThreads=4,得到
(16核)而下边是-XX:ParallelGCThreads=16 -XX:ConcGCThreads=8
(8核)而如果换成UseParallelGC,young gc不错,而full gc偏慢,线上如果没有配置CMS的话,默认是用这个
虽然GC不如物理机,但是可以满足我们的需要了。
注:
1、因为容器不是物理隔离的,比如使用Runtime.getRuntime().availableProcessors() ,会拿到物理CPU个数,而不是容器申请时的个数,
2、CMS在算GC线程时默认是根据物理CPU算的:(http://mail.openjdk.java.net/pipermail/hotspot-gc-dev/2013-November/008952.html )
年轻代的并行线程数(ParallelGCThreads):
return (ncpus <= 8) ? ncpus : MAX2(8, ncpus / 2)
CMS并行线程数(ConcGCThreads):
if (AdjustGCThreadsToCores) {
FLAG_SET_DEFAULT(ConcGCThreads, ParallelGCThreads / 2);
} else {
FLAG_SET_DEFAULT(ConcGCThreads, (3 + ParallelGCThreads) / 4);
}
因为我们升级到了JDK8/Tomcat8, 遇到以下问题:
1、Tomcat8使用Nio2时有时候会遇到如下警告,暂时没有升级上去
org.apache.tomcat.util.net.AbstractEndpoint countDownConnection
WARNING: Incorrect connection count, multiple socket.close called on the same socket.
2、使用G1垃圾回收时,在我们的小堆上没有多大优势,暂时没有使用。
我们线上某服务的JVM参数
export JAVA_OPTS="-Djava.library.path=/usr/local/lib -server -XX:ReservedCodeCacheSize=64m -XX:TLABWasteTargetPercent=10 -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+ParallelRefProcEnabled -XX:+CMSClassUnloadingEnabled -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly -XX:+UnlockDiagnosticVMOptions -XX:ParallelGCThreads=8 -XX:ConcGCThreads=4 -Xss256k -server -Xms2g -Xmx2g -XX:MaxDirectMemorySize=256m -XX:MaxTenuringThreshold=3 -XX:NewRatio=1 -XX:SurvivorRatio=8 -XX:+UnlockDiagnosticVMOptions -XX:ParGCCardsPerStrideChunk=32768 -XX:+AlwaysPreTouch
页:
[1]