Potential memory leak in MetricsClientHttpRequestInterceptor
See original GitHub issueLooks like there’s a bug in this code in org.springframework.boot.actuate.metrics.web.client.MetricsClientHttpRequestInterceptor
class, lines 97 - 99:
if (urlTemplate.get().isEmpty()) {
urlTemplate.remove();
}
I believe the if condition should have a not operator in front of it, meaning item(s) should be removed if the list held by urlTemplate thread-local is not empty.
This came up when looking at a memory leak in code, which is likely an edge case and also uses RestTemplate and UriTemplateHandler in a way some could characterize as misuse. The problem can be reproduced with roughly this kind of logic:
String template = "https://example.org/api/users/{userId}";
for (int i : IntStream.range(0, 10000).toArray()) {
logger.debug("Request to {}", restTemplate.getUriTemplateHandler().expand(template, UUID.randomUUID()));
}
New items are added to the list, but never removed due to the missing not
operator. The accumulated list is visible in heap dump after that loop has finished.
This doesn’t seem to be an issue for example in handling of incoming requests. It also looks like there’s no problem in how RestTemplate uses the mechanism internally. Long-lived thread with manual UriTemplateHandler.expand() usage with metrics actuator enabled is the key.
Issue Analytics
- State:
- Created 2 years ago
- Comments:16 (8 by maintainers)
@sinsuren Spring Boot 2.2.x is missing fixes for bugs in this area such as https://github.com/spring-projects/spring-boot/issues/26915 that’s linked to above. Its open source support also ended in October 2020. You should upgrade to Spring Boot 2.6.x or 2.7.x as soon as possible.
I don’t think we’re going to be able to close this issue in the 2.x line without breaking other use cases. This all comes from the fact that
RestTemplate
is instrumented through a contract that’s not meant for this. We’re going to address this in Spring Framework 6 & Spring Boot 3 by instrumenting the HTTP clients directly with micrometerObservation
.I’m closing in favor of spring-projects/spring-framework#28341