Memory ActiveMQTextMessages从主题中使用后会保存在内存中

Memory ActiveMQTextMessages从主题中使用后会保存在内存中,memory,activemq,messages,Memory,Activemq,Messages,所以我有个问题。我正在我的应用程序中运行一个嵌入式apache.activemq.broker,它有一个主题。我有一个制作人,他向主题发送小消息,而消费者则使用这些消息。 问题是,应用程序的内存占用量一直在不断增长,几天后它会占用数GB的内存。我使用JProfiler进行了内存分析,并注意到许多ActiveMQTextMessage类型的实例都保存在内存中。 我就是这样设立我的经纪人的 BrokerService brokerService = new BrokerService

所以我有个问题。我正在我的应用程序中运行一个嵌入式apache.activemq.broker,它有一个主题。我有一个制作人,他向主题发送小消息,而消费者则使用这些消息。 问题是,应用程序的内存占用量一直在不断增长,几天后它会占用数GB的内存。我使用JProfiler进行了内存分析,并注意到许多ActiveMQTextMessage类型的实例都保存在内存中。 我就是这样设立我的经纪人的

        BrokerService brokerService = new BrokerService();
        brokerService.setUseJmx(false);
        brokerService.setUseLocalHostBrokerName(false);
        brokerService.addConnector(tenantConfiguration.getConnectionString());
        brokerService.setBrokerName(tenantConfiguration.getBrokerComponentIdentifier());
        brokerService.setPersistenceAdapter(persistenceAdapterFromConnectionString);

        SystemUsage systemUsage = new SystemUsage();
        brokerService.setSystemUsage(systemUsage);
        brokerService.setDestinationPolicy(createDestinationPolicyForBrokerService());
下面是我如何设置目的地策略的

private PolicyMap createDestinationPolicyForBrokerService() {
    PolicyMap policyMap = new PolicyMap();

    List<PolicyEntry> policyEntries = new ArrayList<>();

    ConstantPendingMessageLimitStrategy constantPendingMessageLimitStrategy = new ConstantPendingMessageLimitStrategy();
    constantPendingMessageLimitStrategy.setLimit(10);

    PolicyEntry queuePolicyEntry = new PolicyEntry();
    queuePolicyEntry.setPrioritizedMessages(true);
    queuePolicyEntry.setGcInactiveDestinations(true);
    queuePolicyEntry.setInactiveTimoutBeforeGC(86400);
    queuePolicyEntry.setQueue(">");
    queuePolicyEntry.setPendingMessageLimitStrategy(constantPendingMessageLimitStrategy);

    PolicyEntry topicPolicyEntry = new PolicyEntry();
    topicPolicyEntry.setTopic(">");
    topicPolicyEntry.setGcInactiveDestinations(true);
    topicPolicyEntry.setInactiveTimoutBeforeGC(5000);
    topicPolicyEntry.setPendingMessageLimitStrategy(constantPendingMessageLimitStrategy);
    topicPolicyEntry.setUseCache(false);

    policyEntries.add(queuePolicyEntry);
    policyEntries.add(topicPolicyEntry);

    policyMap.setPolicyEntries(policyEntries);
    return policyMap;
}
这就是我发布消息到主题的方式

 public void PublishMessage(string message)
    {
        using (var connection = _connnectionFactory.CreateConnection(user, pwd))
        {
            try
            {
                connection.Start();
                ActiveMQTopic topic = new ActiveMQTopic(TopicName);
                using (var session = connection.CreateSession())
                using (var producer = session.CreateProducer(topic))
                {
                    var textMessage = producer.CreateTextMessage(message);
                    producer.Send(textMessage);
                }
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception);
            }
        }
    }
有人知道为什么邮件在被消费后没有被删除吗


谢谢

通过将我自己的clientId添加到主题连接中,解决了这个问题

_connection = _connnectionFactory.CreateConnection(queueUser, queuePwd);
_connection.ClientId = "MY CLIENT ID";
_connection.Start();

这样,重新启动时就不会创建新的使用者行。

没有代码来帮助查看您正在执行的操作。很难说,GC根目录似乎链接到持久订阅,因此它似乎为某个持久订阅服务器保留了这些行。添加更多信息以帮助我们。我在第一个Post中添加了更多代码经过更多分析后,我发现这是由于camel控制的ACTIVEMQ_ACKS表造成的。这是一个表,broker在其中存储主题的使用者。我注意到,当我重新启动代理应用程序和消费者应用程序时,代理会在该表中添加一个具有唯一id的新消费者,但旧消费者不会被删除,因此消息将永远保留在内存中,因为自从我们重新启动所有内容后,前一消费者不再活动。有没有一种方法可以告诉代理从表中删除旧的消费者?通过将我自己的clientId添加到主题中解决了这个问题
_connection = _connnectionFactory.CreateConnection(queueUser, queuePwd);
_connection.ClientId = "MY CLIENT ID";
_connection.Start();