2016-01-24 47 views
6

配置爲什麼直接ByteBuffer在HornetQ服務器上不斷增加,導致OOM?

我已經建立了獨立的HornetQ在Ubuntu 12.04.3 LTS(GNU/Linux的3.8.0-29-x86_64的仿製)(2.4.7決賽)集羣。該實例具有2個內核的16GB RAM,並且我已將-Xms5G -Xmx10G分配給JVM。

以下是在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個之外的隊列。

問題

經過一段時間的直接ByteBuffer存儲器的大小逐漸增加,甚至佔據交換空間最終投擲的OutOfMemoryError(「直接緩衝存儲器」)。

我嘗試了很多JVM和JMS調優,但徒勞無功。即使爲JVM指定-XX:MaxDirectMemorySize = 4G,也會出於同樣的原因導致早期的OOME。看起來ByteBuffer沒有被讀取,或者GC沒有聲明未被引用的內存。

以前有人遇到同樣的問題嗎?

任何建議,歡迎提前致謝。

+0

你可以用'-Dio.netty.leakDetectionLevel = PARANOID' – Ferrybig

+0

運行java嗎? http://www.evanjones.ca/java-bytebuffer-leak.html –

回答

2

我不知道將hornetq的內部事情,所以這個答案只包括DBBS一般:

  • 其普通泄漏時,DBB對象只是依舊可達,因而不會釋放。這可能是由於應用程序的錯誤或錯誤使用引起的。
    這裏通常的做法是採取堆轉儲並確定保持對象的活性。

  • 緩衝區變得無法訪問,但垃圾收集器執行舊的gen收集,因此很少需要很長時間直到它們被實際收集並且本機內存被釋放。如果服務器以-XX:+DisableExplicitGC運行,那麼當達到MaxDirectMemorySize限制時,還會抑制最後一個完全GC嘗試。
    調整GC以更頻繁地運行以確保及時釋放DBB可以解決這種情況。

+0

我已驗證堆空間管理得相當好,並定期收集垃圾。堆空間永遠不會超過3GB,但緩衝池不斷增加。即使通過Java VisualVM觸發手動GC也不會對其產生影響。 – Tushu

+0

我的答案有兩點。如果你排除了第二個,那麼它可能是第一個。 – the8472

+0

HornetQ內部使用Netty,如果有任何泄漏,那麼它必須是它。這並不能解決我的問題,但我無法做太多的事情。 – Tushu

相關問題