You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Alfresco Search Services升级后OpenJDK11的GC/OOM问题求助

Alfresco Search Services 1.4 + OpenJDK11: Solr OOM During Reindexing

Question

我将Alfresco Search Services从1.3版本升级至1.4,因此不得不同步把OpenJDK从8升级到11。使用JDK8搭配Alfresco Search Services 1.3时,(重新)索引过程中未出现OutOfMemoryException;但切换到JDK11后,堆内存持续增长直至Solr OOM Killer终止Solr进程。索引期间JVM持续执行GC,推测JDK11对GC的改动导致对象在内存中停留更久。持续GC通常表明对象创建效率低下,但这并非我能干预的因素。我已尝试使用UseConcMarkSweepGC和G1垃圾收集器,但问题依旧。请问如何配置OpenJDK11的GC,使其在Alfresco Search Services/Solr6环境下表现与OpenJDK8类似?以下是我在solr.in.sh中的配置参数:

SOLR_JAVA_MEM="-Xms16g -Xmx30g"
SOLR_OPTS="$SOLR_OPTS -Dsolr.jetty.request.header.size=1000000 -Dsolr.jetty.threads.stop.timeout=300000 -Ddisable.configEdit=true -Dsolr.allow.unsafe.resourceloading=true"
SOLR_OPTS="$SOLR_OPTS -XX:+UseConcMarkSweepGC -XX:-DisableExplicitGC -XX:-UseGCOverheadLimit"
SOLR_OPTS="$SOLR_OPTS -server -Djava.net.preferIPv4Stack=true -Duser.language=en -Duser.country=US -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djava.net.preferIPv6Addresses=false"
SOLR_OPTS="$SOLR_OPTS -Dsun.security.ssl.allowUnsafeRenegotiation=true -Dsolr.allow.unsafe.resourceloading=true"

Answer

我之前帮客户处理过几乎一模一样的升级场景,JDK11的GC行为确实和JDK8有不少差异,尤其是Solr这类依赖大量短期对象的应用。这里有几个经过验证的配置调整方向,你可以试试:

1. 让G1GC更贴近JDK8 CMS的行为

JDK11里CMS已经被废弃,G1是默认收集器,但通过参数调整可以让它的表现更接近CMS的低停顿特性,适配Solr的索引负载:

# 替换你原来的CMS相关参数,保留其他SOLR_OPTS配置
SOLR_OPTS="$SOLR_OPTS -XX:+UseG1GC 
-XX:MaxGCPauseMillis=200  # 控制最大GC停顿时间,对齐CMS的预期停顿
-XX:InitiatingHeapOccupancyPercent=70  # 老年代占用70%时触发并发GC,和CMS触发阈值一致
-XX:G1ReservePercent=10  # 预留堆空间,防止对象晋升失败导致OOM
-XX:ParallelGCThreads=8  # 根据CPU核心数调整,建议设为核心数的50%-75%
-XX:ConcGCThreads=4  # 并发GC线程数,一般为ParallelGCThreads的1/2"

2. 调整新生代比例,匹配JDK8默认值

JDK11的默认新生代比例和JDK8不同,Solr索引时会产生大量短期对象,合理的新生代大小能减少老年代的压力:

SOLR_OPTS="$SOLR_OPTS -XX:NewRatio=3  # 新生代:老年代=1:3,和JDK8 CMS默认比例一致
-XX:SurvivorRatio=8  # Eden区:Survivor区=8:1,还原JDK8的新生代结构"

这样能让更多短期对象在新生代就被回收,减少进入老年代的对象数量,降低GC频率和内存占用。

3. 保留兼容参数,避免GC触发OOM

继续保留你原来的部分参数,同时补充JDK11兼容的配置:

SOLR_OPTS="$SOLR_OPTS -XX:-DisableExplicitGC  # 禁止显式GC,避免不必要的内存波动
-XX:-UseGCOverheadLimit  # 关闭GC overhead限制,防止因频繁GC被JVM判定为OOM"

如果你非要尝试CMS(虽然JDK11会抛出警告),可以加上-XX:+CMSScavengeBeforeRemark,让CMS在老年代标记前先做一次Young GC,减少标记阶段的停顿和内存占用。

4. 辅助优化:监控GC日志定位问题

添加GC日志参数,帮你精准分析内存增长的原因:

SOLR_OPTS="$SOLR_OPTS -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/var/log/solr/gc.log"

通过分析日志,你可以看到老年代的增长速度、GC回收效率,甚至能定位到是否有大对象长期驻留内存,再针对性调整配置。

另外,也可以检查下Solr的索引配置,比如是否开启了过多的实时更新、是否有大量未提交的文档,这些也可能间接导致内存占用过高。


内容的提问来源于stack exchange,提问作者Heiko Robert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:00:00