核心思路是明确堆内存瓶颈、合理设定初始与最大值、配合GC策略控制对象生命周期;先查日志确认是否为Java heap space溢出,再通过-Xms与-Xmx设为相等值(如4g)、启用G1GC、限制并发、分批处理报告及开启HeapDump辅助诊断,并持续用jstat和监控验证效果。

核心思路是:明确堆内存瓶颈、合理设定初始与最大值、配合GC策略控制对象生命周期,避免高频调度时老年代快速填满。
确认是否为堆内存溢出(Java heap space)
不是所有 OOM 都是堆问题。先查日志定位类型:
- 执行 tail -n 200 /var/log/jenkins/jenkins.log | grep -i "OutOfMemoryError",重点看是否含 Java heap space
- 若同时发现 OldGen usage: 98% 或频繁 Full GC 日志,基本可锁定堆内存不足
- 排除干扰项:若报错含 Metaspace 或 unable to create new native Thread,则不属于堆调优范畴
设置稳定且匹配硬件的堆参数
关键不是“越大越好”,而是让 JVM 启动即用足合理空间,减少动态扩容开销和碎片化:
- 编辑 /etc/sysconfig/jenkins(RPM 安装)或 /etc/default/jenkins(Debian 系统)
- 在 JENKINS_JAVA_OPTIONS 或 JAVA_ARGS 中写入:
-Xms4g -Xmx4g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 - 建议值参考:物理内存 ≥16GB 时,堆设为 4–6GB;≥32GB 可设至 8GB,但不超过物理内存 50%
- 务必保持 -Xms 与 -Xmx 相等,避免调度高峰时因堆扩展引发卡顿或失败
配合高频调度场景做针对性优化
仅调堆不够,需降低单次构建对堆的瞬时冲击:
- 限制主节点并发数:进入 Manage Jenkins → Nodes → (master) → Configure,将 # of executors 设为 CPU 核心数 × 1.5(如 8 核设为 12),避免线程争抢堆资源
- 禁用大报告一次性加载:若使用 JUnit/Allure,关闭“聚合全部测试结果”选项,改用分模块归档
- 启用堆转储辅助诊断:追加参数 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/jenkins/,OOM 后自动生成 .hprof 文件供 MAT 分析
- 定期清理旧构建:配置 Discard old builds 策略(如保留最近 30 次 + 7 天内),防止历史构建元数据持续占用堆
验证与持续观察
调参后不能只看是否不报错,要确认内存行为真正改善:
- 重启 Jenkins:systemctl restart jenkins
- 运行中观察:jstat -gc $(pgrep -f jenkins.war) 5s,关注 YGC 频率、FGC 是否归零、OldUsed 是否平稳
- 模拟高频调度:用定时任务或 API 连续触发 5–10 个中等规模构建,观察 GC 日志与响应延迟
- 长期监控建议接入 Prometheus + Grafana,跟踪 jvm_memory_used_bytes{area="heap"} 和 jvm_gc_collection_seconds_count


















