spring-boot: Potential memory leak in MetricsClientHttpRequestInterceptor
Looks 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.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 18 (9 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.