Prefer direct io buffers if direct buffers pooled (#9167)

Motivation

Direct buffers are normally preferred when interfacing with raw
sockets. Currently netty will only return direct io buffers (for reading
from a channel) when a platform has unsafe. However, this is
inconsistent with the write-side (filterOutboundMessage) where a direct
byte buffer will be returned if pooling is enabled. This means that
environments without unsafe (and no manual netty configurations) end up
with many pooled heap byte buffers for reading, many pooled direct byte
buffers for writing, and jdk pooled byte buffers (for reading).

Modifications

This commit modifies the AbstractByteBufAllocator to return a direct
byte buffer for io handling when the platform has unsafe or direct byte
buffers are pooled.

Result:

Use direct buffers when direct buffers are pooled for IO.
This commit is contained in:
Tim Brooks 2019-05-21 23:32:41 -06:00 committed by Norman Maurer
parent afdc77f9d3
commit 2dc686ded1
2 changed files with 22 additions and 3 deletions

View File

@ -127,7 +127,7 @@ public abstract class AbstractByteBufAllocator implements ByteBufAllocator {
@Override
public ByteBuf ioBuffer() {
if (PlatformDependent.hasUnsafe()) {
if (PlatformDependent.hasUnsafe() || isDirectBufferPooled()) {
return directBuffer(DEFAULT_INITIAL_CAPACITY);
}
return heapBuffer(DEFAULT_INITIAL_CAPACITY);
@ -135,7 +135,7 @@ public abstract class AbstractByteBufAllocator implements ByteBufAllocator {
@Override
public ByteBuf ioBuffer(int initialCapacity) {
if (PlatformDependent.hasUnsafe()) {
if (PlatformDependent.hasUnsafe() || isDirectBufferPooled()) {
return directBuffer(initialCapacity);
}
return heapBuffer(initialCapacity);
@ -143,7 +143,7 @@ public abstract class AbstractByteBufAllocator implements ByteBufAllocator {
@Override
public ByteBuf ioBuffer(int initialCapacity, int maxCapacity) {
if (PlatformDependent.hasUnsafe()) {
if (PlatformDependent.hasUnsafe() || isDirectBufferPooled()) {
return directBuffer(initialCapacity, maxCapacity);
}
return heapBuffer(initialCapacity, maxCapacity);

View File

@ -92,6 +92,25 @@ public class PooledByteBufAllocatorTest extends AbstractByteBufAllocatorTest<Poo
heapBuffer.release();
}
@Test
public void testIOBuffersAreDirectWhenUnsafeAvailableOrDirectBuffersPooled() {
PooledByteBufAllocator allocator = newAllocator(true);
ByteBuf ioBuffer = allocator.ioBuffer();
assertTrue(ioBuffer.isDirect());
ioBuffer.release();
PooledByteBufAllocator unpooledAllocator = newUnpooledAllocator();
ioBuffer = unpooledAllocator.ioBuffer();
if (PlatformDependent.hasUnsafe()) {
assertTrue(ioBuffer.isDirect());
} else {
assertFalse(ioBuffer.isDirect());
}
ioBuffer.release();
}
@Test
public void testWithoutUseCacheForAllThreads() {
assertFalse(Thread.currentThread() instanceof FastThreadLocalThread);