Buffer leak when handling "Expect:100-continue" requests causes "OutOfMemoryError: Direct buffer memory"

Solution Verified - Updated

Environment

  • JBoss Enterprise Application Platform (EAP) 7.2.x, 7.3.0

Issue

  • The following OutOfMemoryError: Direct buffer memory exception when sending requests with the Expect:100-continue header set:
9:09:26,206 ERROR [org.xnio.listener] (XNIO-1 I/O-1) XNIO001007: A channel event listener threw an exception: java.lang.OutOfMemoryError: Direct buffer memory
	at java.nio.Bits.reserveMemory(Bits.java:694)
	at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
	at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
	at org.xnio.ByteBufferPool$1.createBuffer(ByteBufferPool.java:514)
	at org.xnio.ByteBufferPool.allocateMaster(ByteBufferPool.java:503)
	at org.xnio.ByteBufferPool.access$000(ByteBufferPool.java:42)
	at org.xnio.ByteBufferPool$DefaultCache.allocate(ByteBufferPool.java:780)
	at org.xnio.ByteBufferPool.allocate(ByteBufferPool.java:161)
	at org.xnio.ByteBufferPool$2.createBuffer(ByteBufferPool.java:535)
	at org.xnio.ByteBufferPool.allocateMaster(ByteBufferPool.java:503)
	at org.xnio.ByteBufferPool.access$000(ByteBufferPool.java:42)
	at org.xnio.ByteBufferPool$DefaultCache.allocate(ByteBufferPool.java:780)
	at org.xnio.ByteBufferPool.allocate(ByteBufferPool.java:161)
	at org.xnio.ByteBufferPool.allocate(ByteBufferPool.java:185)
	at org.xnio.ByteBufferPool.allocate(ByteBufferPool.java:171)
	at org.jboss.remoting3.remote.MessageReader.getMessage(MessageReader.java:128)
	at org.jboss.remoting3.remote.ClientConnectionOpenListener$Greeting.handleEvent(ClientConnectionOpenListener.java:170)
	at org.jboss.remoting3.remote.ClientConnectionOpenListener$Greeting.handleEvent(ClientConnectionOpenListener.java:165)
	at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
	at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
	at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:89)
	at org.xnio.nio.WorkerThread.run(WorkerThread.java:591)
  • A heap dump shows growing amounts of DirectByteBuffers in org.xnio.ByteBufferSlicePools
service org.wildfly.extension.io.BufferPoolService @ 0xaaf28960                    |        6,322 |           32 |           404,608 |            32
'- bufferPool org.xnio.ByteBufferSlicePool @ 0xaaf22ee0                            |        6,322 |           48 |           404,608 |        84,568
   '- directBuffers java.util.Collections$SynchronizedRandomAccessList @ 0xaaf29680|        6,322 |           24 |           404,608 |        84,384
      '- list, c java.util.ArrayList @ 0xaaf296b0                                  |        6,322 |           24 |           404,608 |        84,360
         '- elementData java.lang.Object[21079] @ 0xb23529d0                       |        6,322 |       84,336 |           404,608 |        84,336
            |- [4813] java.nio.DirectByteBuffer @ 0xa9ba3c48                       |            1 |           64 |                64 |            64

Resolution

  • Update to 7.2.8 or 7.3.1
  • As a workaround, consider disabling direct buffer usage in the IO subsystem:
            <subsystem xmlns="urn:jboss:domain:io:3.0">
                <worker name="default"/>
                <buffer-pool name="default" direct-buffers="false"/>
            </subsystem>

Root Cause

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.