Lars Haugaard Kristensen created CAMEL-22691:
------------------------------------------------
Summary: Memory leak in CXF producer
Key: CAMEL-22691
URL: https://issues.apache.org/jira/browse/CAMEL-22691
Project: Camel
Issue Type: Bug
Components: camel-cxf
Affects Versions: 4.16.0, 4.14.2, 4.10.7
Environment: Camel Spring Boot 4.10.3
Red Hat OpenJDK 17
REST component is "platform-http"
Embedded web server is Tomcat
OS is RHEL 8.10
Reporter: Lars Haugaard Kristensen
Attachments: cxf-leak-jprofiler.png
Zulip topic: [#camel > Memory leak in CXF
client|https://camel.zulipchat.com/#narrow/channel/257298-camel/topic/Memory.20leak.20in.20CXF.20client/with/555530583]
I'm seeing a memory leak in a production system, leading to OOM. The
application is based on Spring Boot, Tomcat, and platform-http as the rest
component.
I use a REST consumer that performs some mapping, then calls a SOAP service
using CXF. Internally in CXF, a map from Thread to responseContext is not
cleaned up when the exchange completes, and the map simply grows, and entries
are not garbage collected (ref.
org.apache.cxf.endpoint.ClientImpl#responseContext).
I have put together a reproducer which is available on Github:
[https://github.com/Larshk/camel-cxf-leak]
The behavior can be reproduced in Camel versions 4.10.7, 4.14.2, and 4.16.0. I
can work around the problem by setting the following property, which is not
ideal:
{{spring.task.execution.pool.allow-core-thread-timeout=false}}
I found this (old) CXF issue which seems somewhat related:
https://issues.apache.org/jira/browse/CXF-7710
By debugging I see that org.apache.cxf.endpoint.ClientImpl#setResponseContext
is called on two separate threads during the exchange processing, such as:
{noformat}
Response context set on thread task-1, responseContext.size() after: 13
Response context set on thread default-workqueue-4, responseContext.size()
after: 13
Response context set on thread default-workqueue-4, responseContext.size()
after: 13
{noformat}
In this case the "task-1" thread is created by an executor of type:
{{org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor}}
This executor is by default configured to un-alive idle core threads. When
there is low activity, threads are terminated and new are created when needed,
leading to new entries in the responseContext map.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)