Skip to content

Commit

Permalink
Use ByteBufUtil.BYTE_ARRAYS ThreadLocal temporary arrays in more plac…
Browse files Browse the repository at this point in the history
…es (netty#8464)

Motivation:

netty#8388 introduced a reusable ThreadLocal<byte[]> for use in
decodeString(...). It can be used in more places in the buffer package
to avoid temporary allocations of small arrays.

Modifications:

Encapsulate use of the ThreadLocal in a static package-private
ByteBufUtil.threadLocalTempArray(int) method, and make use of it from a
handful of new places including ByteBufUtil.readBytes(...).

Result:

Fewer short-lived small byte array allocations.
  • Loading branch information
njhill authored and normanmaurer committed Nov 5, 2018
1 parent 10539f4 commit 5954110
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 23 deletions.
25 changes: 15 additions & 10 deletions buffer/src/main/java/io/netty/buffer/ByteBufUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public final class ByteBufUtil {
private static final FastThreadLocal<byte[]> BYTE_ARRAYS = new FastThreadLocal<byte[]>() {
@Override
protected byte[] initialValue() throws Exception {
return PlatformDependent.allocateUninitializedArray(1024);
return PlatformDependent.allocateUninitializedArray(MAX_TL_ARRAY_LEN);
}
};

Expand Down Expand Up @@ -95,6 +95,16 @@ protected byte[] initialValue() throws Exception {
logger.debug("-Dio.netty.maxThreadLocalCharBufferSize: {}", MAX_CHAR_BUFFER_SIZE);
}

static final int MAX_TL_ARRAY_LEN = 1024;

/**
* Allocates a new array if minLength > {@link ByteBufUtil#MAX_TL_ARRAY_LEN}
*/
static byte[] threadLocalTempArray(int minLength) {
return minLength <= MAX_TL_ARRAY_LEN ? BYTE_ARRAYS.get()
: PlatformDependent.allocateUninitializedArray(minLength);
}

/**
* Returns a <a href="http://en.wikipedia.org/wiki/Hex_dump">hex dump</a>
* of the specified buffer's readable bytes.
Expand Down Expand Up @@ -768,11 +778,7 @@ static String decodeString(ByteBuf src, int readerIndex, int len, Charset charse
array = src.array();
offset = src.arrayOffset() + readerIndex;
} else {
if (len <= 1024) {
array = BYTE_ARRAYS.get();
} else {
array = PlatformDependent.allocateUninitializedArray(len);
}
array = threadLocalTempArray(len);
offset = 0;
src.getBytes(readerIndex, array, 0, len);
}
Expand Down Expand Up @@ -1392,7 +1398,9 @@ static void readBytes(ByteBufAllocator allocator, ByteBuffer buffer, int positio
int chunkLen = Math.min(length, WRITE_CHUNK_SIZE);
buffer.clear().position(position);

if (allocator.isDirectBufferPooled()) {
if (length <= MAX_TL_ARRAY_LEN || !allocator.isDirectBufferPooled()) {
getBytes(buffer, threadLocalTempArray(length), 0, chunkLen, out, length);
} else {
// if direct buffers are pooled chances are good that heap buffers are pooled as well.
ByteBuf tmpBuf = allocator.heapBuffer(chunkLen);
try {
Expand All @@ -1402,9 +1410,6 @@ static void readBytes(ByteBufAllocator allocator, ByteBuffer buffer, int positio
} finally {
tmpBuf.release();
}
} else {
byte[] tmp = PlatformDependent.allocateUninitializedArray(length);
getBytes(buffer, tmp, 0, chunkLen, out, length);
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions buffer/src/main/java/io/netty/buffer/PooledDirectByteBuf.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package io.netty.buffer;

import io.netty.util.Recycler;
import io.netty.util.internal.PlatformDependent;

import java.io.IOException;
import java.io.InputStream;
Expand Down Expand Up @@ -352,8 +351,8 @@ public ByteBuf setBytes(int index, ByteBuffer src) {
@Override
public int setBytes(int index, InputStream in, int length) throws IOException {
checkIndex(index, length);
byte[] tmp = PlatformDependent.allocateUninitializedArray(length);
int readBytes = in.read(tmp);
byte[] tmp = ByteBufUtil.threadLocalTempArray(length);
int readBytes = in.read(tmp, 0, length);
if (readBytes <= 0) {
return readBytes;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/
package io.netty.buffer;

import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.StringUtil;

import java.io.IOException;
Expand Down Expand Up @@ -356,11 +355,11 @@ public ByteBuf getBytes(int index, OutputStream out, int length) throws IOExcept
if (buffer.hasArray()) {
out.write(buffer.array(), index + buffer.arrayOffset(), length);
} else {
byte[] tmp = PlatformDependent.allocateUninitializedArray(length);
byte[] tmp = ByteBufUtil.threadLocalTempArray(length);
ByteBuffer tmpBuf = internalNioBuffer();
tmpBuf.clear().position(index);
tmpBuf.get(tmp);
out.write(tmp);
tmpBuf.get(tmp, 0, length);
out.write(tmp, 0, length);
}
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -561,8 +561,8 @@ public int setBytes(int index, InputStream in, int length) throws IOException {
if (buffer.hasArray()) {
return in.read(buffer.array(), buffer.arrayOffset() + index, length);
} else {
byte[] tmp = PlatformDependent.allocateUninitializedArray(length);
int readBytes = in.read(tmp);
byte[] tmp = ByteBufUtil.threadLocalTempArray(length);
int readBytes = in.read(tmp, 0, length);
if (readBytes <= 0) {
return readBytes;
}
Expand Down
7 changes: 3 additions & 4 deletions buffer/src/main/java/io/netty/buffer/UnsafeByteBufUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,9 @@ static void getBytes(AbstractByteBuf buf, long addr, int index, OutputStream out
buf.checkIndex(index, length);
if (length != 0) {
int len = Math.min(length, ByteBufUtil.WRITE_CHUNK_SIZE);
if (buf.alloc().isDirectBufferPooled()) {
if (len <= ByteBufUtil.MAX_TL_ARRAY_LEN || !buf.alloc().isDirectBufferPooled()) {
getBytes(addr, ByteBufUtil.threadLocalTempArray(length), 0, len, out, length);
} else {
// if direct buffers are pooled chances are good that heap buffers are pooled as well.
ByteBuf tmpBuf = buf.alloc().heapBuffer(len);
try {
Expand All @@ -594,9 +596,6 @@ static void getBytes(AbstractByteBuf buf, long addr, int index, OutputStream out
} finally {
tmpBuf.release();
}
} else {
byte[] tmp = PlatformDependent.allocateUninitializedArray(len);
getBytes(addr, tmp, 0, len, out, length);
}
}
}
Expand Down

0 comments on commit 5954110

Please sign in to comment.