zhouerla 发表于 2016-1-11 14:41:15

使用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]
查看完整版本: 使用Docker容器时需要更改GC并发参数配置