Spring-boot: Large number of "SimplePauseDetectorThread_0" threads in GradleWorkerMain

Created on 8 Jan 2019  路  3Comments  路  Source: spring-projects/spring-boot

Hi!

I have a somewhat complicated Spring Boot app, with a large number of tests.

When running the tests, it seems to be accumulating a lot of threads, one of which there is multiple instances of and is called "SimplePauseDetectorThread_0", which I traced down to this dependency

|    |    |    \--- io.micrometer:micrometer-core:1.1.1
|    |    |         +--- org.latencyutils:LatencyUtils:2.0.3

This seems to happen on Spring Boot 2.0.6 as well as 2.1.1.

A typical test may look like this:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@ActiveProfiles(profiles = {"test"})
public class MyTest {
[...]

My actuator config looks like this:

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

Please see the attached screenshots:

screenshot 2019-01-08 at 22 30 01

screenshot 2019-01-08 at 22 32 09

Please tell me if I can be of further assistance.

Thanks!

Most helpful comment

Hi!

Thank you so much for that information, it was just what I needed. It took a while to figure out what this meant in practice for my Gradle setup:

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.

Which did not help much, but fortunately I found this text in the code for org.springframework.core.SpringProperties

Reads a {@code spring.properties} file from the root of the Spring library classpath

It did not make immediate sense to me, but after thinking about it for a while I figured out that it probably means I can put the file in my-service/src/test/resources/spring.properties, which I did and I popped this one in there:

spring.test.context.cache.maxSize=1

Now my tests are running nicely with less memory consumption, fewer threads, and (unscientifically) it felt faster. This also means I can use Gradle's org.gradle.parallel=true with higher confidence since each sub project will consume less computer resources when running in parallel.

This also resolves the issue with Gradle 5+ having workers that have 512MB max heap by default (instead of 25% of system RAM) - the subproject test suites no longer blow away all the available RAM which would cause the workers to OOM if I did not add a custom jvmargs with a larger heap in the test configuration of java projects. I can now run with "vanilla" heap size in the gradle worker.

I wrote the above as detailed as I could so that is preserved for posterity. I also created this StackOverflow post.

All 3 comments

I have a somewhat complicated Spring Boot app, with a large number of tests.

Thanks for the report but it's hard to know what is going on with the details that you've shared. 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.

Please review the documentation regarding context caching. If that guess does not match your setup, please share more details, a small sample would be ideal.

Hi!

Thank you so much for that information, it was just what I needed. It took a while to figure out what this meant in practice for my Gradle setup:

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.

Which did not help much, but fortunately I found this text in the code for org.springframework.core.SpringProperties

Reads a {@code spring.properties} file from the root of the Spring library classpath

It did not make immediate sense to me, but after thinking about it for a while I figured out that it probably means I can put the file in my-service/src/test/resources/spring.properties, which I did and I popped this one in there:

spring.test.context.cache.maxSize=1

Now my tests are running nicely with less memory consumption, fewer threads, and (unscientifically) it felt faster. This also means I can use Gradle's org.gradle.parallel=true with higher confidence since each sub project will consume less computer resources when running in parallel.

This also resolves the issue with Gradle 5+ having workers that have 512MB max heap by default (instead of 25% of system RAM) - the subproject test suites no longer blow away all the available RAM which would cause the workers to OOM if I did not add a custom jvmargs with a larger heap in the test configuration of java projects. I can now run with "vanilla" heap size in the gradle worker.

I wrote the above as detailed as I could so that is preserved for posterity. I also created this StackOverflow post.

Very nice @bes and thanks for the feedback. I am glad you were able to resolve this issue.

Was this page helpful?
0 / 5 - 0 ratings