Question

I am seeing a very odd memory leak in Camel (2.10.3) when consuming from a Tibco topic (using tibjms 4.4.3 library). From looking at heap dumps it appears that the memory consumption is a huge amount of ConcurrentHashMap stuff (Segment, HashEntry[], locks etc).

What I believe is happening is that the exchanges coming in from the topic are never getting marked as 'complete' by Camel, and it is holding onto references to them in memory. The problem goes away when I route them to '.stop()'.

I create a JMS Component with:

    TibjmsConnectionFactory connectionFactory = new TibjmsConnectionFactory();
    connectionFactory.setServerUrl(properties.getProperty(endpoints.getServerUrl()));
    connectionFactory.setUserName(properties.getProperty(endpoints.getUsername()));
    connectionFactory.setUserPassword(properties.getProperty(endpoints.getPassword()));

    JmsComponent emsComponent = JmsComponent.jmsComponent(connectionFactory);

    return emsComponent;

Register it on the context with:

    camelContext.addComponent("positionems", emsComponent);

Then have created an incredibly simple test route just to reproduce the problem:

    from("positionems:topic:UK.TOPIC4")
    .to("mock:out");

What is interesting is that this will fill up the heap with ConcurrentHashMap stuff until the process falls over with Heap Space errors. BUT it runs fine forever if I change the route to:

    from("positionems:topic:UK.TOPIC4")
    .stop();

According to the javadoc for stop, it "Stops continue routing the current org.apache.camel.Exchange and marks it as completed." - presumably 'marks it as completed' is what I am missing when I send it to mock (or indeed when I run my full normal program, which behaves the same way memory-wise as sending it to mock).

I have tried lots of variations of the Jms route config, for example:

    from("positionems:topic:UK.TOPIC4?disableReplyTo=true&deliveryPersistent=false")

And I have tried setting the route never to expect a response, but maybe I am doing this wrong:

    from("positionems:topic:UK.TOPIC4")
    .inOnly()         // marked as deprecated?
    .to("mock:out");

Is this a problem specifically with Tibco? Given the number of people that use ActiveMQ with no issues I find it hard to believe I have found an actual bug in Camel, hopefully I am doing something really simple wrong!

EDIT

I have tested with the latest Camel version (2.12.1) and this seems to be a bit better (number of ConcurrentHashMap Segments grows slower) but is still definitely a problem.

Was it helpful?

Solution

You send the message to "mock:out" endpoint which keeps a copy of the message in memory. So there is your leak :) - What you can do is to either configure the mock endpoint to not retain so many messages (see the documentation), or maybe better send the message to a log endpoint or something.

At the mock documentation there is this big red warning, which tells about the in-memory copy: http://camel.apache.org/mock

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top