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:
parent
afdc77f9d3
commit
2dc686ded1
@ -127,7 +127,7 @@ public abstract class AbstractByteBufAllocator implements ByteBufAllocator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf ioBuffer() {
|
public ByteBuf ioBuffer() {
|
||||||
if (PlatformDependent.hasUnsafe()) {
|
if (PlatformDependent.hasUnsafe() || isDirectBufferPooled()) {
|
||||||
return directBuffer(DEFAULT_INITIAL_CAPACITY);
|
return directBuffer(DEFAULT_INITIAL_CAPACITY);
|
||||||
}
|
}
|
||||||
return heapBuffer(DEFAULT_INITIAL_CAPACITY);
|
return heapBuffer(DEFAULT_INITIAL_CAPACITY);
|
||||||
@ -135,7 +135,7 @@ public abstract class AbstractByteBufAllocator implements ByteBufAllocator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf ioBuffer(int initialCapacity) {
|
public ByteBuf ioBuffer(int initialCapacity) {
|
||||||
if (PlatformDependent.hasUnsafe()) {
|
if (PlatformDependent.hasUnsafe() || isDirectBufferPooled()) {
|
||||||
return directBuffer(initialCapacity);
|
return directBuffer(initialCapacity);
|
||||||
}
|
}
|
||||||
return heapBuffer(initialCapacity);
|
return heapBuffer(initialCapacity);
|
||||||
@ -143,7 +143,7 @@ public abstract class AbstractByteBufAllocator implements ByteBufAllocator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf ioBuffer(int initialCapacity, int maxCapacity) {
|
public ByteBuf ioBuffer(int initialCapacity, int maxCapacity) {
|
||||||
if (PlatformDependent.hasUnsafe()) {
|
if (PlatformDependent.hasUnsafe() || isDirectBufferPooled()) {
|
||||||
return directBuffer(initialCapacity, maxCapacity);
|
return directBuffer(initialCapacity, maxCapacity);
|
||||||
}
|
}
|
||||||
return heapBuffer(initialCapacity, maxCapacity);
|
return heapBuffer(initialCapacity, maxCapacity);
|
||||||
|
@ -92,6 +92,25 @@ public class PooledByteBufAllocatorTest extends AbstractByteBufAllocatorTest<Poo
|
|||||||
heapBuffer.release();
|
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
|
@Test
|
||||||
public void testWithoutUseCacheForAllThreads() {
|
public void testWithoutUseCacheForAllThreads() {
|
||||||
assertFalse(Thread.currentThread() instanceof FastThreadLocalThread);
|
assertFalse(Thread.currentThread() instanceof FastThreadLocalThread);
|
||||||
|
Loading…
Reference in New Issue
Block a user