我有一个有点复杂的 Spring Boot 应用程序,包含大量测试。
在运行测试时,它似乎积累了很多线程,其中一个线程有多个实例并且被称为SimplePauseDetectorThread_0
,我追溯到这个依赖
| | | \--- io.micrometer:micrometer-core:1.1.1
| | | +--- org.latencyutils:LatencyUtils:2.0.3
这似乎发生在 Spring Boot 2.0.6 和 2.1.1 上。
一个典型的测试可能是这样的:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@ActiveProfiles(profiles = {"test"})
public class MyTest {
[...]
我的执行器配置如下所示:
management.endpoints.enabled-by-default=false
management.endpoint.prometheus.enabled=true
management.endpoints.web.base-path=/
management.endpoints.web.exposure.include=prometheus
management.endpoints.web.path-mapping.prometheus=prometheus
spring.metrics.prometheus.enabled=true
见附件截图
最佳答案
Snicoll from Pivotal helped me on GitHub ,通过暗示它可能连接到 spring boot 测试框架中的上下文缓存。
If you have a large number of tests that are using the spring integration and a somewhat important number of context configurations (you've only shown one class), then one context per configuration will be created and I can see the number of threads increasing in that scenario.
然后他将我指向了 relevant documentation ,其中指出:
You can configure the maximum size from the command line or a build script by setting a JVM system property named spring.test.context.cache.maxSize. As an alternative, you can set the same property programmatically by using the SpringProperties API.
org.springframework.core.SpringProperties
声明:
Reads a {@code spring.properties} file from the root of the Spring library classpath
这给我们留下了两种设置 maxSize
的方法。
方案一.配置gradle测试任务
在 build.gradle
中向 gradle test
任务添加一个属性,它将配置 GradleWorkerMain
:
test {
jvmArgs "-Dspring.test.context.cache.maxSize=1"
}
如果您有很多子项目,您可能希望使用此选项。
请参阅下面的Bonus,了解将设置应用于所有子项目的方法。
选项 2. 将 spring.properties 添加到您的测试资源
你可以把设置写在my-service/src/test/resources/spring.properties
中,像这样:
spring.test.context.cache.maxSize=1
结论
现在我的测试运行良好,内存消耗更少,线程更少。
奖金
这也解决了 Gradle 5+ 默认情况下拥有 512MB 最大堆(而不是系统 RAM 的 25%)的 worker 的问题 - 子项目测试套件不再耗尽所有可用 RAM,这会导致 worker OOM如果我没有在 java
项目的 test
配置中添加具有更大堆的自定义 jvmargs。我现在可以在 gradle worker 中以“vanilla”堆大小运行。
如果确实想调整可用于 Gradle 测试的 RAM,请在根 build.gradle
中执行类似的操作:
allprojects { project ->
project.plugins.withId('java') {
test {
maxHeapSize = "1536M"
// If you don't want to use spring.properties (or add other JVM args)
jvmArgs "-Dspring.test.context.cache.maxSize=1"
}
}
project.plugins.withId('java-library') {
test {
maxHeapSize = "1536M"
// If you don't want to use spring.properties (or add other JVM args)
jvmArgs "-Dspring.test.context.cache.maxSize=1"
}
}
}
关于java - Spring 集成测试消耗大量内存,在 GradleWorkerMain 中使用大量重复线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54117965/