当从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的数量增长较慢),但仍然是一个问题。
答案 0 :(得分:1)
您将消息发送到“mock:out”端点,该端点将消息的副本保留在内存中。你有泄漏:) - 你可以做的是配置模拟端点不保留这么多消息(参见文档),或者更好地将消息发送到日志端点或其他东西。
在模拟文档中有一个大红色警告,它告诉内存副本:http://camel.apache.org/mock