背景
今天在线上灰度部署服务的时候,容器循环重启。没法排查启动失败原因。(同样配置、代码在沙箱没问题)
经云平台同事告知后开启容器debug模式,debug模式下,容器不会重启。
重新部署后,登上机器查看jdk启动日志,报下列错误
Java HotSpot(TM) 64-Bit Server VM warning: Can't have more ConcGCThreads (8) than ParallelGCThreads (4).
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
排查原因
我们知道ConcGCThreads是g1的并发标记线程数配置。通过启动报错知道,不能比ParallelGCThreads设置更多的ConcGCThreads线程。
查看服务器配置
-Xms4g -Xmx4g -Xss1024K -XX:SurvivorRatio=65536 -XX:MetaspaceSize=512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:ConcGCThreads=8 -XX:G1HeapRegionSize=16m -Dfastjson.parser.safeMode=true
没有配置ParallelGCThreads,那么ParallelGCThreads走默认的配置,如果cpu小于8,则使用cpu核数,和报错一样,我的cpu核数是4
默认情况下,G1垃圾收集器会将ConcGCThreads这个线程总数设置为并行垃圾线程数(-XX:ParallelGCThreads)的四分之一
设置的是8,远高于默认值。
怀疑
怀疑是使用的jvm版本做了限制。因为上线时间较赶,依赖于qa时间,我又没上线权限,没法一一验证,于是直接替换cms解决。
比较好奇的是,回滚到原版本,一样的配置就没有问题。。
解决方法
替换为CMS
-Xms4g -Xmx4g -Xmn1g -Xss1024K -XX:PermSize=256m -XX:MaxPermSize=512m -XX:+CMSPermGenSweepingEnabled -XX:SurvivorRatio=8 -XX:MaxDirectMemorySize=2g -XX:-OmitStackTraceInFastThrow -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=80 -Dfastjson.parser.safeMode=true
git commitlog
G1启动报错导致线上部署失败Can't have more ConcGCThreads (8) than ParallelGCThreads (4).
应用只用到4g,且该机器只4核,不太适合G1
其实我们设置下两个参数符合规则就行,但是我这个机器就4g,算了吧