本地 16G 内存跑得好好的,CI 上 gradle test 跑到第七个模块报 Metaspace,进程 exit 137,构建直接中断。碰到这种情况,我一般先确认改动有没有真的生效。

原因不复杂,测试 JVM 的 Metaspace 上限默认不大,每个 fork 都要加载一遍 Spring 上下文和动态生成的类。CI 容器内存小,多个 worker 同时起就顶到上限。

「测试 JVM OOM」这类改动最怕改一半,回滚脚本先准备好,再动生产。改完顺手把文档补一句,省得下次自己重新推一遍。

tasks.withType(Test) {
  maxHeapSize = "1g"
  jvmArgs "-XX:MaxMetaspaceSize=512m"
  forkEvery = 200
}

监控和日志的时间要对上,时区不一致会多绕很大一圈。临时改动用注释写上日期和原因,过两周自己都记不清为什么这么写。

动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。一次只改一处,改完立刻验证,几个改动叠在一起,出问题就说不清是谁导致的。

具体做法是,给 test 任务单独设 maxMetaspaceSize 和 heap;开 forkEvery 让 JVM 定期重启 释放加载的类;CI 上把 maxParallelForks 调到 2 先跑通;用 --no-daemon 排除守护进程占内存。

最后用这个标准收尾,CI 跑到最后一个模块不再 exit 137 内存曲线保持在容器上限以下。

作者 9823189