From 3db0128db981d689d50fecf1bdecfd9797b5350c Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Wed, 13 Aug 2014 11:55:06 +0200 Subject: [PATCH] [#2762] Not expand ByteBuffer[] in ChannelOutboundBuffer Motivation: At the moment we expand the ByteBuffer[] when we have more then 1024 ByteBuffer to write and replace the stored instance in its FastThreadLocal. This is not needed and may even harm performance on linux as IOV_MAX is 1024 and so this may cause the JVM to do an array copy. Modifications: Just exit the nioBuffers() method if we can not fit more ByteBuffer in the array. This way we will pick them up on the next call. Result: Remove uncessary array copy and simplify the code. --- .../netty/channel/ChannelOutboundBuffer.java | 27 +++++-------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java b/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java index b74e1793f3..4fb43fd53f 100644 --- a/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java +++ b/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java @@ -46,6 +46,10 @@ public final class ChannelOutboundBuffer { private static final FastThreadLocal NIO_BUFFERS = new FastThreadLocal() { @Override protected ByteBuffer[] initialValue() throws Exception { + // Use 1024 as this is the IOV_MAX value on linux. If you sue a bigger one the JDK may do some array + // copy which we should not trigger. + // + // See 'man 2 writev' for more informations. return new ByteBuffer[1024]; } }; @@ -355,8 +359,8 @@ public final class ChannelOutboundBuffer { int count = buf.nioBufferCount(); int neededSpace = nioBufferCount + count; if (neededSpace > nioBuffers.length) { - nioBuffers = expandNioBufferArray(nioBuffers, neededSpace, nioBufferCount); - NIO_BUFFERS.set(threadLocalMap, nioBuffers); + // We have not enough space left in the array to add the ByteBuffers so break here. + break; } if (count == 1) { ByteBuffer nioBuf = buf.internalNioBuffer(readerIndex, readableBytes); @@ -385,25 +389,6 @@ public final class ChannelOutboundBuffer { return nioBufferCount; } - private static ByteBuffer[] expandNioBufferArray(ByteBuffer[] array, int neededSpace, int size) { - int newCapacity = array.length; - do { - // double capacity until it is big enough - // See https://github.com/netty/netty/issues/1890 - newCapacity <<= 1; - - if (newCapacity < 0) { - throw new IllegalStateException(); - } - - } while (neededSpace > newCapacity); - - ByteBuffer[] newArray = new ByteBuffer[newCapacity]; - System.arraycopy(array, 0, newArray, 0, size); - - return newArray; - } - /** * Returns the number of {@link ByteBuffer} that can be written out of the {@link ByteBuffer} array that was * obtained via {@link #nioBuffers()}. This method MUST be called after {@link #nioBuffers()}