Affects: spring-messaging:5.3.18, spring-boot-starter-websocket:2.6.6


using a SimpMessagingTemplate and calling

var someObject = ... // about 3-4 level nested Map<String, Object>
messageTemplate.convertAndSend("/some/endpoint", someObject);

leaks AtomicReference's via

AbstractMessageSendingTemplate::convertAndSend(D,Object)
AbstractMessageSendingTemplate::convertAndSend(D,Object,(Map)null)
AbstractMessageSendingTemplate::convertAndSend(D,Object,Map,(MessagePostProcessor)null)
AbstractMessageSendingTemplate::doConvert(Object,Map,(MessagePostProcessor)null)
AbstractMessageConverter::toMessage(Object, MessageHeaders)
AbstractMessageConverter::toMessage(Object, MessageHeaders, (Object) null)
MappingJackson2MessageConverter::canConvertTo(Object, MessageHeaders)
AtomicReference.<init>

this implementation, on successful call to the ObjectMapper's method canSerialize can/has shown leak of the AtomicReference (pointing to null).

In our use case we had a stomp endpoint be updated every second (using @Scheduled), the highest count of AtomicReferences has been seen in our production-environment with 57 million instances (1GB memory) leaked after 16 hours in use.

We are running Java17.0.4 Eclipse Adoptium on a RedHat docker container on Linux infrastructure. I cannot provide much more info, as I do not know anything more. Reproduced with same project locally on windows, on java 17.0.3 Adoptium.

This issue is/may be with jackson as well, we are slightly behind running 2.13.2.

I have looked in the source for yours and jackson, and cannot immediately see why this would happen (I see no reason why the AtomicReference would not be collected for garbage).

Comment From: MikkelHJuul

After a routine check I will add that this leak only happens in one of our applications running the same code. so this is a leak that happens under very specific loads. maybe this is more of a JVM issue then. fortunately we could simply remove the websocket, as this was related to a backend service where someone made a dashboard/web page that should have just been metrics; removing websocket updates from this endpoint is an easy choice.

it seems like the API decision of handing over the AtomicReference to a long-running instance makes it hard for the JVM to determine if it can be collected. I also see that this ObjectMapper method is being removed from Jackson3, because it's, in their own wording: "hard to use right"

Comment From: MikkelHJuul

We have uncovered this issue to be jackson-databind#3665 that we got via Jsonata4java referencing v2.14.0-rc2 I apologize for the fuzz

Comment From: bclozel

Thanks for letting us know.