Gradle批量执行测试时出现OutOfMemory错误,单独运行该测试可通过
测试套件批量运行OOM排查方案
注意:当前测试本身逻辑简单、单独运行正常,说明它只是内存累积到阈值的触发点,不是问题根因
1. 堆内存配置与泄漏定位
- 先调整Gradle测试任务的JVM参数,开启堆转储方便定位,在
build.gradle的test配置块增加以下内容:
test { jvmArgs '-Xmx4g', '-Xms2g', '-XX:+HeapDumpOnOutOfMemoryError', '-XX:HeapDumpPath=./test-heap-dump.hprof' }
拿到堆转储文件后可通过JProfiler、VisualVM等工具分析大对象、未回收引用,重点排查Spring上下文实例、Mock对象、异步线程持有的资源是否存在泄漏。
- 检查Spring测试上下文缓存策略:Spring Boot测试默认会缓存相同配置的上下文,若你的测试套件中存在大量不同配置的
@SpringBootTest(比如不同的@ActiveProfiles、@MockBean、@Import配置),会导致大量不可复用的上下文积压在内存中。可在测试类上加@DirtiesContext注解,跑完当前测试类直接销毁对应上下文,验证是否为上下文缓存过多导致的OOM。
2. 异步线程资源泄漏排查
报错中的OOM均出现在exchange相关异步线程上,重点排查异步线程池配置:
- 虽然当前测试类Mock了
AsyncService,但要确认是否存在遗漏Mock的异步调用逻辑,或是业务代码中线程池核心线程数设置过大、线程无自动回收规则。如果业务线程池用了无界队列,测试过程中累积的任务过多也会导致内存溢出。 - 检查测试结束后是否有主动清理异步资源的逻辑,是否存在未关闭的线程池、未执行完的异步任务持有大对象无法回收的情况。
3. 测试运行策略验证
- 调整Gradle测试运行参数,限制并行度、分批执行测试,避免一次性加载过多测试资源,可在
gradle.properties中添加配置:
org.gradle.test.maxParallelForks = 2 org.gradle.jvmargs = -Xmx4g
- 单独运行前193个测试,不执行后续测试,若仍出现OOM,直接确认是前192个测试累积的内存泄漏导致的问题。
- 排查前面的测试类是否存在大对象未清理、静态变量持有大量集合数据未重置的情况,这类累积泄漏通常会在某个随机测试运行时触发OOM。
4. 测试工具与Mock清理检查
- 检查
StyleCCTestUtility类的构造、测试数据生成方法是否会生成大量大对象,是否存在将测试数据存入静态集合未清理的逻辑。 - 可在测试类的
@AfterEach方法中调用Mockito.reset()重置所有@MockBean,避免Mock的应答逻辑持有对象无法回收。
内容的提问来源于stack exchange,提问作者ng.newbie
相关产品推荐
相关产品推荐

