OutOfDirectMemoryError raised from Netty

Solution Unverified - Updated

Environment

Red Hat JBoss Enterprise Application Platform 7.2.4

Issue

We were getting an OutOfDirectMemoryError raised from Netty. After setting batch-delay to 0 in http-connector as shown in https://access.redhat.com/solutions/3204251

We use the same memory settings as EAP 6 and expect EAP 7 to work with the same settings.

The latest log shows the same issue is there but now coming from large messages

2019-11-12T14:23:41.077+00:00@vio-5653-jms-0@JMS@WARN  [org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnection] (Thread-3301 (ActiveMQ-server-org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl$6@5a221463)) Trying to allocate 102426 bytes, System is throwing OutOfMemoryError on NettyConnection org.apache.activemq.artemis.core.remoting.impl.netty.NettyServerConnection@3f502f5a[ID=142b15a4, local= /x.y.z.50:5445, remote=/x.y.z.7:41430], there are currently pendingWrites: [NETTY] -> 0 causes: failed to allocate 16777216 byte(s) of direct memory (used: 3221225472, max: 3221225472): io.netty.util.internal.OutOfDirectMemoryError: failed to allocate 16777216 byte(s) of direct memory (used: 3221225472, max: 3221225472)#012#011at io.netty.util.internal.PlatformDependent.incrementMemoryCounter(PlatformDependent.java:656)#012#011at io.netty.util.internal.PlatformDependent.allocateDirectNoCleaner(PlatformDependent.java:611)#012#011at io.netty.buffer.PoolArena$DirectArena.allocateDirect(PoolArena.java:768)#012#011at io.netty.buffer.PoolArena$DirectArena.newChunk(PoolArena.java:744)#012#011at io.netty.buffer.PoolArena.allocateNormal(PoolArena.java:245)#012#011at io.netty.buffer.PoolArena.allocate(PoolArena.java:227)#012#011at io.netty.buffer.PoolArena.allocate(PoolArena.java:147)#012#011at io.netty.buffer.PooledByteBufAllocator.newDirectBuffer(PooledByteBufAllocator.java:327)#012#011at io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:187)#012#011at io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:178)#012#011at org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnection.createTransportBuffer(NettyConnection.java:253)#012#011at org.apache.activemq.artemis.spi.core.protocol.AbstractRemotingConnection.createTransportBuffer(AbstractRemotingConnection.java:188)#012#011at org.apache.activemq.artemis.core.protocol.core.impl.PacketImpl.createPacket(PacketImpl.java:354)#012#011at org.apache.activemq.artemis.core.protocol.core.impl.PacketImpl.encode(PacketImpl.java:320)#012#011at org.apache.activemq.artemis.core.protocol.core.impl.ChannelImpl.send(ChannelImpl.java:294)#012#011at org.apache.activemq.artemis.core.protocol.core.impl.ChannelImpl.send(ChannelImpl.java:238)#012#011at org.apache.activemq.artemis.core.protocol.core.impl.CoreSessionCallback.sendLargeMessageContinuation(CoreSessionCallback.java:111)#012#011at org.apache.activemq.artemis.core.server.impl.ServerConsumerImpl$LargeMessageDeliverer.deliver(ServerConsumerImpl.java:1336)#012#011at org.apache.activemq.artemis.core.server.impl.ServerConsumerImpl$2.run(ServerConsumerImpl.java:1189)#012#011at org.apache.activemq.artemis.utils.actors.OrderedExecutor.doTask(OrderedExecutor.java:42)#012#011at org.apache.activemq.artemis.utils.actors.OrderedExecutor.doTask(OrderedExecutor.java:31)#012#011at org.apache.activemq.artemis.utils.actors.ProcessorBase.executePendingTasks(ProcessorBase.java:66)#012#011at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [rt.jar:1.8.0_221]#012#011at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [rt.jar:1.8.0_221]#012#011at org.apache.activemq.artemis.utils.ActiveMQThreadFactory$1.run(ActiveMQThreadFactory.java:118)#012

but now the issue is occurs when large messages are being used- "org.apache.activemq.artemis.core.protocol.core.impl.CoreSessionCallback.sendLargeMessageContinuation(CoreSessionCallback.java:111"

Resolution

Set batch-delay to 0 in http-connector as shown in https://access.redhat.com/solutions/3204251

Setting io.netty.maxDirectMemory=0 will instruct netty to use the JVM direct memory pool, and the JVM JMX stats[1] can be seen.
Increase MaxDirectMemorySize to the same size as the heap and monitor further, change MaxDirectMemorySize if necessary, based on load tests. It may turn out that leaving MaxDirectMemorySize unset is sufficient as, by default, the size is set to 0, meaning that the JVM chooses the size for NIO direct-buffer allocations automatically[2].

[1] Content from github.com is not included.https://github.com/netty/netty/issues/6349
[2] Content from docs.oracle.com is not included.https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html

Root Cause

The use of direct memory has increased in the version of Netty used in EAP 7 when compared to the version used in EAP 6 so expect an increase if the value of MaxDirectMemorySize was previously set for EAP 6.

Diagnostic Steps

Observe stack trace.

Components
Category

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.