2016-01-24 19 views
6

KonfigurationWarum nimmt Direct ByteBuffer auf dem HornetQ Server zu OOM zu?

ich Setup eine eigenständige HornetQ (2.4.7-Final) Cluster auf Ubuntu 12.04.3 LTS (GNU/Linux 3.8.0-29-generic x86_64). Die Instanz hat 16 GB RAM mit 2 Kernen und ich habe -Xms5G -Xmx10G der JVM zugewiesen.

Im Folgenden ist die Adresseinstellung in der HornetQ Konfiguration:

<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> 

sind 10 andere Warteschlangen an die Default-Adresse durch Platzhalter angegeben gebunden.

Problem

über einen Zeitraum von den Direkt ByteBuffer Speicher nehmen allmählich in der Größe Zeit und nehmen auch die Swap-Speicher OutOfMemoryError schließlich werfen ("Direct Pufferspeicher").

Ich habe viel JVM und JMS-Tuning versucht, aber vergeblich. Selbst die Angabe einer -XX: MaxDirectMemorySize = 4G an die JVM führte aus demselben Grund zu einem frühen OOME. Es scheint, dass entweder der ByteBuffer nicht gelesen wird oder GC den nicht referenzierten Speicher nicht beansprucht.

Hat jemand schon einmal mit dem gleichen Problem konfrontiert?

Alle Vorschläge sind willkommen und bedanken sich im Voraus.

+0

Können Sie laufen Java mit '-Dio.netty.leakDetectionLevel = PARANOID' – Ferrybig

+0

Diesem verwandt? http://www.evanjones.ca/java-bytebuffer-leak.html –

Antwort

2

Ich weiß nichts über HornetQ Interna, so dass diese Antwort deckt nur DBBS im Allgemeinen:

  • seine ein gewöhnliches Leck, die DBB-Objekte sind einfach noch erreichbar und somit nicht befreit. Dies könnte entweder auf einen Fehler oder eine falsche Verwendung der Anwendung zurückzuführen sein.
    Der übliche Ansatz hier ist, einen Heap-Dump zu nehmen und festzustellen, was die Objekte am Leben erhält.

  • Die Puffer werden nicht erreichbar, aber der Garbage Collector führt eine alte Gen-Sammlung so selten durch, dass es lange dauert, bis sie tatsächlich gesammelt und der native Speicher freigegeben wird. Wenn der Server mit -XX:+DisableExplicitGC läuft, wird auch der letzte Full-GC-Versuch unterdrückt, wenn das MaxDirectMemorySize Limit erreicht ist.
    Das Tuning des GC, um häufiger zu laufen, um eine rechtzeitige Freigabe der DBBs zu gewährleisten, könnte diesen Fall lösen.

+0

Ich habe überprüft, dass Heap-Platz recht gut verwaltet wird und regelmäßig Müll gesammelt wird. Der Heap-Speicher reicht nie über 3 GB, aber der Buffer-Pool steigt weiter an. Auch das Auslösen eines manuellen GC über Java VisualVM hat keinen Einfluss darauf. – Tushu

+0

meine Antwort hat zwei Punkte. Wenn du den zweiten ausgeschlossen hast, dann ist es wahrscheinlich der erste. – the8472

+0

HornetQ intern Netty verwendet und wenn es ein Leck gibt, dann muss es sein. Dies löst jedoch nicht mein Problem, da ich nicht viel dagegen tun kann. – Tushu