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