CentOS 上 Jenkins 内存溢出的排查与解决
一 快速定位与应急
- 确认溢出类型与位置
- 查看 /var/log/jenkins/jenkins.log,搜索关键字 OutOfMemoryError。常见两类:
- Java heap space:JVM 堆内存不足,多与构建并发、构建过程内存占用高有关。
- PermGen/Metaspace:类元数据区不足,常见于较老 Java 7/8 或插件/构建产物过多场景。
- 应急缓解
- 临时降低并发构建数(Manage Jenkins → Nodes → 主节点 → Configure → # of executors),避免继续触发 OOM。
- 重启 Jenkins 释放堆:systemctl restart jenkins。
- 若属于 Tomcat 部署的 Jenkins,需同时调整 Tomcat 的 JAVA_OPTS(见下文“部署方式差异”)。
二 调整 JVM 堆与元空间参数
- 推荐在 CentOS 的 RPM 包安装下,编辑 /etc/sysconfig/jenkins,通过 JENKINS_JAVA_OPTIONS 设置堆与元空间(示例为 2GB 堆,可按机器内存调整):
- 编辑配置
- vi /etc/sysconfig/jenkins
- 在 JENKINS_JAVA_OPTIONS 中设置:
- JENKINS_JAVA_OPTIONS=“-Djava.awt.headless=true -Xms2048m -Xmx2048m -XX:MaxNewSize=512m”
- 说明:
- 将 -Xms 与 -Xmx 设为相同值可减少堆动态扩展开销;-XX:MaxNewSize 控制年轻代大小。
- 若仍使用 Java 7/8 且出现 PermGen 错误,可追加 -XX:PermSize=… -XX:MaxPermSize=…(Java 8 的 Metaspace 一般不需要显式设置 MaxMetaspaceSize,除非要限制上限)。
- 重启生效
- systemctl restart jenkins
- 其他安装方式的位置
- 若使用 war 包 + systemd,在 unit 文件或 jenkins.xml 的 arguments 中追加 -Xmx/-Xms 等参数。
- 若部署在 Tomcat,需在 /etc/default/tomcat7(或相应 Tomcat 配置)中设置 JAVA_OPTS,如:
- JAVA_OPTS=“-Djava.awt.headless=true -Xms2048m -Xmx2048m -XX:MaxNewSize=512m”
- 注意:不要同时在多个位置设置堆参数,避免冲突;修改后务必重启对应进程。
三 按场景优化以减少 OOM 触发
- 构建与任务层面
- 控制并发:将 # of executors 设置为与 CPU/内存相匹配的值,避免并发过高导致堆被占满。
- 分批处理大任务:例如处理大规模 JUnit XML 报告时,拆分为多个模块/批次逐步收集,显著降低单次内存峰值。
- 清理历史数据:定期删除旧构建与工作空间,减少插件与构建产物对堆与元空间的长期占用。
- 架构层面
- 启用 分布式构建(添加 Agent 节点),把重构建任务从主节点剥离,降低主节点内存压力。
- 插件与系统层面
- 精简插件:卸载不再使用的插件,减少启动与运行期内存开销;保持插件更新以修复性能/内存问题。
- 资源升级:在预算允许时扩充服务器内存、使用 SSD、提升 CPU 核数,改善整体吞吐与 I/O。
四 监控与参数建议
- 监控手段
- 使用 Java VisualVM 或 JConsole 远程连接(开启 JMX),观察堆使用曲线、GC 行为、线程与类加载情况,据监控结果微调 -Xmx/-Xms/-XX:MaxNewSize 等参数。
- 参数建议与示例
- 一般将 -Xms 与 -Xmx 设为相同,避免运行期扩容抖动;年轻代 -XX:MaxNewSize 可按总堆的约 1/4 起步,再结合 GC 日志微调。
- 示例(4GB 内存的服务器,可按需下调或上调):
- JENKINS_JAVA_OPTIONS=“-Djava.awt.headless=true -Xms4096m -Xmx4096m -XX:MaxNewSize=1024m”
- 若为 Java 7/8 且出现 PermGen 错误,可追加:
- -XX:PermSize=256m -XX:MaxPermSize=512m
- 修改后重启并持续观察日志与监控,确认 OOM 是否消除且 GC 健康。