Open chrisgleissner opened 6 days ago
Thanks for the sample.
Actuator doesn't appear to be relevant to the problem as it can be reproduced with a dependency on only spring-boot-starter-web
and the following main class:
package com.example.gh_43276;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
public class Gh43276Application {
@GetMapping
String ping() {
return "pong";
}
public static void main(String[] args) {
SpringApplication.run(Gh43276Application.class, args);
}
}
Repeatedly accessing http://localhost:8080 during startup will then trigger the problem. It appears that enabling lazy initialization is required as I've been unable to reproduce without it.
If you want to keep lazy initialization enabled, the problem can also be avoided by setting spring.mvc.servlet.load-on-startup=0
. This will ensure that DispatcherServlet
is initialized on the main thread rather than on a potentially virtual request-handling thread.
The synchronisation in Tomcat's StandardWrapper
and Framework's FrameworkServlet
hasn't changed. What has changed is the locking in DefaultSingletonBeanRegistry
and I think it's this change in Framework 6.2 that's causing that synchronisation to now be flagged as a cause of pinning. We'll transfer this issue to the Framework team so that they can consider any changes that may be appropriate here.
Thanks for the detailed analysis and the workaround @wilkinsona. Much appreciated.
I have tried the work-around in my sample project and as per https://github.com/chrisgleissner/spring-boot-3.4-pinned-thread-during-launch-issue/actions/runs/12016916807/job/33498136714#step:4:47, the thread pinning no longer occurs.
I will use this workaround until the root issue is fixed.
Problem
When using Spring Boot 3.4.0 combined with Spring WebMVC, virtual threads, and lazy bean initialization, accessing
/actuator/health
during the application launch results in a pinned virtual thread.This is a regression from Spring Boot 3.3.6 where this issue does not occur.
Sample App
This issue is demonstrated in https://github.com/chrisgleissner/spring-boot-3.4-pinned-thread-during-launch-issue:
Details
Start process that continuously calls /actuator/health:
Start Spring Boot app
Software Versions
Source code
build.gradle.kts
:src/main/java/com/example/demo/DemoApplication.java
:src/main/resources/application.yaml
:Expected Logs (Spring Boot 3.3.6)
No thread pinning detected.
Actual Logs (Spring Boot 3.4.0)
Thread pinning detected.
Monitors
This section shows the relevant code for each of the stack trace lines ending with
<== monitors:1
in the stack trace above.Monitor
Log:
Code:
Monitor
Log:
Code:
Monitor
Log:
Code: