配置
我在Ubuntu 12.04.3 LTS(GNU / Linux 3.8.0-29-generic x86_64)上设置了一个独立的HornetQ(2.4.7-Final)集群。该实例有16GB RAM和2个内核,我已经为JVM分配了-Xms5G -Xmx10G。
以下是HornetQ配置中的地址设置:
<address-settings>
<address-setting match="jms.queue.pollingQueue">
<dead-letter-address>jms.queue.DLQ</dead-letter-address>
<expiry-address>jms.queue.ExpiryQueue</expiry-address>
<redelivery-delay>86400000</redelivery-delay>
<max-delivery-attempts>10</max-delivery-attempts>
<max-size-bytes>1048576000</max-size-bytes>
<page-size-bytes>10485760</page-size-bytes>
<address-full-policy>PAGE</address-full-policy>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
</address-setting>
<address-setting match="jms.queue.offerQueue">
<dead-letter-address>jms.queue.DLQ</dead-letter-address>
<expiry-address>jms.queue.ExpiryQueue</expiry-address>
<redelivery-delay>3600000</redelivery-delay>
<max-delivery-attempts>25</max-delivery-attempts>
<max-size-bytes>1048576000</max-size-bytes>
<page-size-bytes>10485760</page-size-bytes>
<address-full-policy>PAGE</address-full-policy>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
</address-setting>
<address-setting match="jms.queue.smsQueue">
<dead-letter-address>jms.queue.DLQ</dead-letter-address>
<expiry-address>jms.queue.ExpiryQueue</expiry-address>
<redelivery-delay>3600000</redelivery-delay>
<max-delivery-attempts>25</max-delivery-attempts>
<max-size-bytes>1048576000</max-size-bytes>
<page-size-bytes>10485760</page-size-bytes>
<address-full-policy>PAGE</address-full-policy>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
</address-setting>
<!--default for catch all-->
<!-- delay redelivery of messages for 1hr -->
<address-setting match="#">
<dead-letter-address>jms.queue.DLQ</dead-letter-address>
<expiry-address>jms.queue.ExpiryQueue</expiry-address>
<redelivery-delay>3600000</redelivery-delay>
<max-delivery-attempts>25</max-delivery-attempts>
<max-size-bytes>1048576000</max-size-bytes>
<page-size-bytes>10485760</page-size-bytes>
<address-full-policy>PAGE</address-full-policy>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
</address-setting>
</address-settings>
其他10个队列绑定到通配符指定的默认地址。
问题
在一段时间内,Direct ByteBuffer内存的大小逐渐增加,甚至占用交换空间,最终抛出OutOfMemoryError(&#34;直接缓冲内存&#34;)。
我已经尝试过很多JVM和JMS调优但是徒劳无功。即使为JVM指定-XX:MaxDirectMemorySize = 4G也会导致早期的OOME出于同样的原因。似乎没有读取ByteBuffer或者GC没有声明未引用的内存。
以前有人遇到过同样的问题吗?
欢迎任何建议,并提前致谢。
答案 0 :(得分:2)
我对hornetq的内部结构一无所知,所以这个答案只涵盖了DBB:
它是一个普通的泄漏,DBB对象仍然可以访问,因此不会被释放。这可能是由于应用程序中的错误或错误使用造成的。
通常的方法是进行堆转储并确定使对象保持活动的原因。
缓冲区变得无法访问,但垃圾收集器执行旧的gen集合很少,直到它们实际被收集并且本机内存被释放需要很长时间。如果服务器以-XX:+DisableExplicitGC
运行,则还会在达到MaxDirectMemorySize
限制时抑制最后一次尝试Full GC。
调整GC以更频繁地运行以确保及时释放DBB可以解决这种情况。