Change ByteBufAllocator.buffer() to allocate a direct buffer only when the platform can handle a direct buffer reliably
- Rename directbyDefault to preferDirect - Add a system property 'io.netty.prederDirect' to allow a user from changing the preference on launch-time - Merge UnpooledByteBufAllocator.DEFAULT_BY_* to DEFAULT
This commit is contained in:
parent
a8a7c4f576
commit
8d88acb4a7
@ -16,6 +16,8 @@
|
||||
|
||||
package io.netty.buffer;
|
||||
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
|
||||
/**
|
||||
* Skeltal {@link ByteBufAllocator} implementation to extend.
|
||||
*/
|
||||
@ -34,10 +36,11 @@ public abstract class AbstractByteBufAllocator implements ByteBufAllocator {
|
||||
/**
|
||||
* Create new instance
|
||||
*
|
||||
* @param directByDefault {@code true} if direct buffers should be used by default.
|
||||
* @param preferDirect {@code true} if {@link #buffer(int)} should try to allocate a direct buffer rather than
|
||||
* a heap buffer
|
||||
*/
|
||||
protected AbstractByteBufAllocator(boolean directByDefault) {
|
||||
this.directByDefault = directByDefault;
|
||||
protected AbstractByteBufAllocator(boolean preferDirect) {
|
||||
directByDefault = preferDirect && PlatformDependent.hasUnsafe();
|
||||
emptyBuf = new UnpooledHeapByteBuf(this, 0, 0);
|
||||
}
|
||||
|
||||
@ -65,6 +68,14 @@ public abstract class AbstractByteBufAllocator implements ByteBufAllocator {
|
||||
return heapBuffer(initialCapacity, maxCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf ioBuffer() {
|
||||
if (PlatformDependent.hasUnsafe()) {
|
||||
return directBuffer(0);
|
||||
}
|
||||
return heapBuffer(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf heapBuffer() {
|
||||
return heapBuffer(256, Integer.MAX_VALUE);
|
||||
|
@ -55,7 +55,7 @@ public final class EmptyByteBuf implements ByteBuf {
|
||||
|
||||
@Override
|
||||
public ByteBufAllocator alloc() {
|
||||
return UnpooledByteBufAllocator.HEAP_BY_DEFAULT;
|
||||
return UnpooledByteBufAllocator.DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package io.netty.buffer;
|
||||
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
@ -31,7 +32,8 @@ public class PooledByteBufAllocator extends AbstractByteBufAllocator {
|
||||
private static final int MIN_PAGE_SIZE = 4096;
|
||||
private static final int MAX_CHUNK_SIZE = (int) (((long) Integer.MAX_VALUE + 1) / 2);
|
||||
|
||||
public static final PooledByteBufAllocator DEFAULT = new PooledByteBufAllocator();
|
||||
public static final PooledByteBufAllocator DEFAULT =
|
||||
new PooledByteBufAllocator(PlatformDependent.directBufferPreferred());
|
||||
|
||||
private final PoolArena<byte[]>[] heapArenas;
|
||||
private final PoolArena<ByteBuffer>[] directArenas;
|
||||
@ -49,8 +51,8 @@ public class PooledByteBufAllocator extends AbstractByteBufAllocator {
|
||||
this(false);
|
||||
}
|
||||
|
||||
public PooledByteBufAllocator(boolean directByDefault) {
|
||||
this(directByDefault, DEFAULT_NUM_HEAP_ARENA, DEFAULT_NUM_DIRECT_ARENA, DEFAULT_PAGE_SIZE, DEFAULT_MAX_ORDER);
|
||||
public PooledByteBufAllocator(boolean preferDirect) {
|
||||
this(preferDirect, DEFAULT_NUM_HEAP_ARENA, DEFAULT_NUM_DIRECT_ARENA, DEFAULT_PAGE_SIZE, DEFAULT_MAX_ORDER);
|
||||
}
|
||||
|
||||
public PooledByteBufAllocator(int nHeapArena, int nDirectArena, int pageSize, int maxOrder) {
|
||||
@ -141,11 +143,6 @@ public class PooledByteBufAllocator extends AbstractByteBufAllocator {
|
||||
return cache.directArena.allocate(cache, initialCapacity, maxCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf ioBuffer() {
|
||||
return directBuffer(0);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(heapArenas.length);
|
||||
|
@ -75,7 +75,7 @@ import java.util.Queue;
|
||||
*/
|
||||
public final class Unpooled {
|
||||
|
||||
private static final ByteBufAllocator ALLOC = UnpooledByteBufAllocator.HEAP_BY_DEFAULT;
|
||||
private static final ByteBufAllocator ALLOC = UnpooledByteBufAllocator.DEFAULT;
|
||||
|
||||
/**
|
||||
* Big endian byte order.
|
||||
|
@ -22,11 +22,11 @@ import io.netty.util.internal.PlatformDependent;
|
||||
*/
|
||||
public final class UnpooledByteBufAllocator extends AbstractByteBufAllocator {
|
||||
|
||||
public static final UnpooledByteBufAllocator HEAP_BY_DEFAULT = new UnpooledByteBufAllocator(false);
|
||||
public static final UnpooledByteBufAllocator DIRECT_BY_DEFAULT = new UnpooledByteBufAllocator(true);
|
||||
public static final UnpooledByteBufAllocator DEFAULT =
|
||||
new UnpooledByteBufAllocator(PlatformDependent.directBufferPreferred());
|
||||
|
||||
private UnpooledByteBufAllocator(boolean directByDefault) {
|
||||
super(directByDefault);
|
||||
public UnpooledByteBufAllocator(boolean preferDirect) {
|
||||
super(preferDirect);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -38,12 +38,4 @@ public final class UnpooledByteBufAllocator extends AbstractByteBufAllocator {
|
||||
protected ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity) {
|
||||
return new UnpooledDirectByteBuf(this, initialCapacity, maxCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf ioBuffer() {
|
||||
if (PlatformDependent.hasUnsafe()) {
|
||||
return directBuffer(0);
|
||||
}
|
||||
return heapBuffer(0);
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,6 @@ public class BigEndianHeapByteBufTest extends AbstractByteBufTest {
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void shouldNotAllowNullInConstructor2() {
|
||||
new UnpooledHeapByteBuf(UnpooledByteBufAllocator.HEAP_BY_DEFAULT, null, 0);
|
||||
new UnpooledHeapByteBuf(UnpooledByteBufAllocator.DEFAULT, null, 0);
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,9 @@ public final class PlatformDependent {
|
||||
|
||||
private static final boolean HAS_UNSAFE = hasUnsafe0();
|
||||
private static final boolean CAN_USE_CHM_V8 = HAS_UNSAFE && JAVA_VERSION < 8;
|
||||
private static final boolean DIRECT_BUFFER_PREFERRED =
|
||||
HAS_UNSAFE && SystemPropertyUtil.getBoolean("io.netty.preferDirect", false);
|
||||
|
||||
private static final long ARRAY_BASE_OFFSET = arrayBaseOffset0();
|
||||
|
||||
private static final boolean HAS_JAVASSIST = hasJavassist0();
|
||||
@ -97,6 +100,14 @@ public final class PlatformDependent {
|
||||
return HAS_UNSAFE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the platform has reliable low-level direct buffer access API and a user specified
|
||||
* {@code -Dio.netty.preferDirect} option.
|
||||
*/
|
||||
public static boolean directBufferPreferred() {
|
||||
return DIRECT_BUFFER_PREFERRED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if and only if Javassist is available.
|
||||
*/
|
||||
@ -160,13 +171,6 @@ public final class PlatformDependent {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to allocate a new direct {@link ByteBuffer} using the best available allocator.
|
||||
*/
|
||||
public static ByteBuffer newDirectBuffer(int capacity) {
|
||||
return PlatformDependent0.newDirectBuffer(capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to deallocate the specified direct {@link ByteBuffer}. Please note this method does nothing if
|
||||
* the current platform does not support this operation or the specified buffer is not a direct buffer.
|
||||
|
@ -119,14 +119,6 @@ final class PlatformDependent0 {
|
||||
return UNSAFE != null;
|
||||
}
|
||||
|
||||
static ByteBuffer newDirectBuffer(int capacity) {
|
||||
if (hasUnsafe()) {
|
||||
return ByteBuffer.allocateDirect(capacity);
|
||||
} else {
|
||||
throw new Error("refusing to create a direct buffer without proper access to the low-level API");
|
||||
}
|
||||
}
|
||||
|
||||
static void freeDirectBuffer(ByteBuffer buffer) {
|
||||
Cleaner cleaner;
|
||||
try {
|
||||
|
@ -28,7 +28,9 @@ import java.util.Deque;
|
||||
|
||||
public class ByteBufAllocatorBenchmark extends DefaultBenchmark {
|
||||
|
||||
private static final ByteBufAllocator POOLED_ALLOCATOR_HEAP = PooledByteBufAllocator.DEFAULT;
|
||||
private static final ByteBufAllocator UNPOOLED_ALLOCATOR_HEAP = new UnpooledByteBufAllocator(false);
|
||||
private static final ByteBufAllocator UNPOOLED_ALLOCATOR_DIRECT = new UnpooledByteBufAllocator(true);
|
||||
private static final ByteBufAllocator POOLED_ALLOCATOR_HEAP = new PooledByteBufAllocator(false);
|
||||
private static final ByteBufAllocator POOLED_ALLOCATOR_DIRECT = new PooledByteBufAllocator(true);
|
||||
|
||||
@Param({"0", "256", "1024", "4096", "16384", "65536"})
|
||||
@ -71,13 +73,13 @@ public class ByteBufAllocatorBenchmark extends DefaultBenchmark {
|
||||
UNPOOLED_HEAP {
|
||||
@Override
|
||||
ByteBufAllocator alloc() {
|
||||
return UnpooledByteBufAllocator.HEAP_BY_DEFAULT;
|
||||
return UNPOOLED_ALLOCATOR_HEAP;
|
||||
}
|
||||
},
|
||||
UNPOOLED_DIRECT {
|
||||
@Override
|
||||
ByteBufAllocator alloc() {
|
||||
return UnpooledByteBufAllocator.DIRECT_BY_DEFAULT;
|
||||
return UNPOOLED_ALLOCATOR_DIRECT;
|
||||
}
|
||||
},
|
||||
POOLED_HEAP {
|
||||
|
Loading…
Reference in New Issue
Block a user