0

从 Tibco 主题(使用 tibjms 4.4.3 库)消费时,我在 Camel (2.10.3) 中看到一个非常奇怪的内存泄漏。从堆转储来看,内存消耗似乎是大量的 ConcurrentHashMap 东西(Segment、HashEntry[]、锁等)。

我认为正在发生的事情是,来自该主题的交流永远不会被 Camel 标记为“完整”,并且它会在内存中保留对它们的引用。当我将它们路由到“.stop()”时,问题就消失了。

我创建了一个 JMS 组件:

    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;

在上下文中注册它:

    camelContext.addComponent("positionems", emsComponent);

然后创建了一个非常简单的测试路线来重现问题:

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

有趣的是,这将用 ConcurrentHashMap 的东西填满堆,直到进程因堆空间错误而崩溃。但是,如果我将路线更改为:

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

根据停止的 javadoc,它“停止继续路由当前的 org.apache.camel.Exchange 并将其标记为已完成。” - 大概“将其标记为已完成”是我将其发送到模拟时所缺少的(或者实际上当我运行完整的正常程序时,它的行为方式与将其发送到模拟的内存方式相同)。

我已经尝试了很多 Jms 路由配置的变体,例如:

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

而且我已经尝试设置路线永远不会期望得到响应,但也许我做错了:

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

这是 Tibco 特有的问题吗?鉴于使用 ActiveMQ 没有任何问题的人数,我很难相信我在 Camel 中发现了一个实际的错误,希望我做错了一些非常简单的错误!

编辑

我已经使用最新的 Camel 版本(2.12.1)进行了测试,这似乎要好一些(ConcurrentHashMap Segments 的数量增长较慢)但仍然绝对是一个问题。

4

1 回答 1

1

您将消息发送到“mock:out”端点,该端点将消息的副本保存在内存中。所以有你的泄漏:) - 你可以做的是配置模拟端点不保留这么多消息(参见文档),或者更好地将消息发送到日志端点或其他东西。

在模拟文档中有这个大红色警告,它讲述了内存中的副本:http ://camel.apache.org/mock

于 2013-10-17T13:28:05.803 回答