【问题标题】:ActiveMQ memory leak - Understanding objects in the heapActiveMQ 内存泄漏 - 了解堆中的对象
【发布时间】:2017-06-23 19:32:12
【问题描述】:

我的 ActiveMQ 堆大小不断增加,最终内存不足。为一个仍在运行的实例获取堆转储,并得到以下具有大量实例的类(其余类非常少)。寻找有关此处可能出现问题的指示。

170866 instances of class org.apache.activemq.command.ProducerId
170526 instances of class org.apache.activemq.broker.jmx.AnnotatedMBean
170519 instances of class org.apache.activemq.command.SessionId
170518 instances of class org.apache.activemq.command.ConnectionId
170482 instances of class org.apache.activemq.broker.ProducerBrokerExchange
170482 instances of class org.apache.activemq.broker.jmx.ProducerView
170482 instances of class org.apache.activemq.command.ProducerInfo
170482 instances of class org.apache.activemq.state.ProducerState

发送消息的代码 sn-p:

MessageProducer messageProducer = session.createProducer(topic);
messageProducer.setTimeToLive(5 * 60 * 1000);
Message message = session.createObjectMessage(agentDebugEvent);
messageProducer.send(message);

是不是因为messageProducer.close()不见了?

【问题讨论】:

    标签: java memory-leaks activemq


    【解决方案1】:

    如果您为每个消息发送创建生产者并且从不关闭它们,那么将为这些生产者构建 JMX MBean,因为每个生产者都暴露在 JMX 树中,以便管理和调试它们正在执行的操作。您当然可以关闭 JMX,这会降低开销,但您仍然会慢慢走向 Broker 的最终死亡,因为它仍然需要跟踪附加的生产者。

    如果你想做这样的事情(我不知道你为什么会这样做),你可以切换到 JMS 池,这会做一些资源池,这样你就可以在每次发送时创建一个生产者只会使用缓存的匿名生产者。实际上,尽管这通常是一个糟糕的设计,但您应该评估为什么您认为需要按照这些思路做某事。

    创建 MessageProducer 是一项代价高昂的操作,涉及网络往返、创建代理端资源(如 MBean 等)。如果您正在寻找发送者的性能,那么创建一个生产者并继续重用它。

    【讨论】:

    • 我认为不关闭生产者是我拥有的代码中的一个错误。每次我必须发送消息时,对所有消息使用单个生产者是否比创建新生产者有任何优势?
    • 创建一个消费者是一个重量级的操作,如果你想要高性能发送,那么使用一个生产者。
    猜你喜欢
    • 1970-01-01
    • 2019-06-02
    • 2019-12-13
    • 2012-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-31
    • 1970-01-01
    相关资源
    最近更新 更多