Hide Recycler implemention to allow experimenting with different implementions of an Object pool (#9715)
Motivation: At the moment we directly extend the Recycler base class in our code which makes it hard to experiment with different Object pool implementation. It would be nice to be able to switch from one to another by using a system property in the future. This would also allow to more easily test things like https://github.com/netty/netty/pull/8052. Modifications: - Introduce ObjectPool class with static method that we now use internally to obtain an ObjectPool implementation. - Wrap the Recycler into an ObjectPool and return it for now Result: Preparation for different ObjectPool implementations
This commit is contained in:
parent
aa3c57508b
commit
6c061abc49
@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
package io.netty.buffer;
|
package io.netty.buffer;
|
||||||
|
|
||||||
import io.netty.util.Recycler.Handle;
|
|
||||||
import io.netty.util.ReferenceCounted;
|
import io.netty.util.ReferenceCounted;
|
||||||
|
import io.netty.util.internal.ObjectPool.Handle;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
|
@ -18,10 +18,11 @@ package io.netty.buffer;
|
|||||||
import io.netty.util.AsciiString;
|
import io.netty.util.AsciiString;
|
||||||
import io.netty.util.ByteProcessor;
|
import io.netty.util.ByteProcessor;
|
||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
import io.netty.util.Recycler;
|
|
||||||
import io.netty.util.Recycler.Handle;
|
|
||||||
import io.netty.util.concurrent.FastThreadLocal;
|
import io.netty.util.concurrent.FastThreadLocal;
|
||||||
import io.netty.util.internal.MathUtil;
|
import io.netty.util.internal.MathUtil;
|
||||||
|
import io.netty.util.internal.ObjectPool;
|
||||||
|
import io.netty.util.internal.ObjectPool.Handle;
|
||||||
|
import io.netty.util.internal.ObjectPool.ObjectCreator;
|
||||||
import io.netty.util.internal.PlatformDependent;
|
import io.netty.util.internal.PlatformDependent;
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
import io.netty.util.internal.SystemPropertyUtil;
|
import io.netty.util.internal.SystemPropertyUtil;
|
||||||
@ -1171,13 +1172,13 @@ public final class ByteBufUtil {
|
|||||||
|
|
||||||
static final class ThreadLocalUnsafeDirectByteBuf extends UnpooledUnsafeDirectByteBuf {
|
static final class ThreadLocalUnsafeDirectByteBuf extends UnpooledUnsafeDirectByteBuf {
|
||||||
|
|
||||||
private static final Recycler<ThreadLocalUnsafeDirectByteBuf> RECYCLER =
|
private static final ObjectPool<ThreadLocalUnsafeDirectByteBuf> RECYCLER =
|
||||||
new Recycler<ThreadLocalUnsafeDirectByteBuf>() {
|
ObjectPool.newPool(new ObjectCreator<ThreadLocalUnsafeDirectByteBuf>() {
|
||||||
@Override
|
@Override
|
||||||
protected ThreadLocalUnsafeDirectByteBuf newObject(Handle<ThreadLocalUnsafeDirectByteBuf> handle) {
|
public ThreadLocalUnsafeDirectByteBuf newObject(Handle<ThreadLocalUnsafeDirectByteBuf> handle) {
|
||||||
return new ThreadLocalUnsafeDirectByteBuf(handle);
|
return new ThreadLocalUnsafeDirectByteBuf(handle);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
static ThreadLocalUnsafeDirectByteBuf newInstance() {
|
static ThreadLocalUnsafeDirectByteBuf newInstance() {
|
||||||
ThreadLocalUnsafeDirectByteBuf buf = RECYCLER.get();
|
ThreadLocalUnsafeDirectByteBuf buf = RECYCLER.get();
|
||||||
@ -1205,12 +1206,13 @@ public final class ByteBufUtil {
|
|||||||
|
|
||||||
static final class ThreadLocalDirectByteBuf extends UnpooledDirectByteBuf {
|
static final class ThreadLocalDirectByteBuf extends UnpooledDirectByteBuf {
|
||||||
|
|
||||||
private static final Recycler<ThreadLocalDirectByteBuf> RECYCLER = new Recycler<ThreadLocalDirectByteBuf>() {
|
private static final ObjectPool<ThreadLocalDirectByteBuf> RECYCLER = ObjectPool.newPool(
|
||||||
|
new ObjectCreator<ThreadLocalDirectByteBuf>() {
|
||||||
@Override
|
@Override
|
||||||
protected ThreadLocalDirectByteBuf newObject(Handle<ThreadLocalDirectByteBuf> handle) {
|
public ThreadLocalDirectByteBuf newObject(Handle<ThreadLocalDirectByteBuf> handle) {
|
||||||
return new ThreadLocalDirectByteBuf(handle);
|
return new ThreadLocalDirectByteBuf(handle);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
static ThreadLocalDirectByteBuf newInstance() {
|
static ThreadLocalDirectByteBuf newInstance() {
|
||||||
ThreadLocalDirectByteBuf buf = RECYCLER.get();
|
ThreadLocalDirectByteBuf buf = RECYCLER.get();
|
||||||
|
@ -20,9 +20,10 @@ package io.netty.buffer;
|
|||||||
import static io.netty.util.internal.ObjectUtil.checkPositiveOrZero;
|
import static io.netty.util.internal.ObjectUtil.checkPositiveOrZero;
|
||||||
|
|
||||||
import io.netty.buffer.PoolArena.SizeClass;
|
import io.netty.buffer.PoolArena.SizeClass;
|
||||||
import io.netty.util.Recycler;
|
|
||||||
import io.netty.util.Recycler.Handle;
|
|
||||||
import io.netty.util.internal.MathUtil;
|
import io.netty.util.internal.MathUtil;
|
||||||
|
import io.netty.util.internal.ObjectPool;
|
||||||
|
import io.netty.util.internal.ObjectPool.Handle;
|
||||||
|
import io.netty.util.internal.ObjectPool.ObjectCreator;
|
||||||
import io.netty.util.internal.PlatformDependent;
|
import io.netty.util.internal.PlatformDependent;
|
||||||
import io.netty.util.internal.logging.InternalLogger;
|
import io.netty.util.internal.logging.InternalLogger;
|
||||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||||
@ -492,12 +493,12 @@ final class PoolThreadCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
private static final Recycler<Entry> RECYCLER = new Recycler<Entry>() {
|
private static final ObjectPool<Entry> RECYCLER = ObjectPool.newPool(new ObjectCreator<Entry>() {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
protected Entry newObject(Handle<Entry> handle) {
|
public Entry newObject(Handle<Entry> handle) {
|
||||||
return new Entry(handle);
|
return new Entry(handle);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,7 @@
|
|||||||
|
|
||||||
package io.netty.buffer;
|
package io.netty.buffer;
|
||||||
|
|
||||||
import io.netty.util.Recycler;
|
import io.netty.util.internal.ObjectPool.Handle;
|
||||||
import io.netty.util.Recycler.Handle;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@ -29,7 +28,7 @@ import java.nio.channels.ScatteringByteChannel;
|
|||||||
|
|
||||||
abstract class PooledByteBuf<T> extends AbstractReferenceCountedByteBuf {
|
abstract class PooledByteBuf<T> extends AbstractReferenceCountedByteBuf {
|
||||||
|
|
||||||
private final Recycler.Handle<PooledByteBuf<T>> recyclerHandle;
|
private final Handle<PooledByteBuf<T>> recyclerHandle;
|
||||||
|
|
||||||
protected PoolChunk<T> chunk;
|
protected PoolChunk<T> chunk;
|
||||||
protected long handle;
|
protected long handle;
|
||||||
@ -42,7 +41,7 @@ abstract class PooledByteBuf<T> extends AbstractReferenceCountedByteBuf {
|
|||||||
private ByteBufAllocator allocator;
|
private ByteBufAllocator allocator;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected PooledByteBuf(Recycler.Handle<? extends PooledByteBuf<T>> recyclerHandle, int maxCapacity) {
|
protected PooledByteBuf(Handle<? extends PooledByteBuf<T>> recyclerHandle, int maxCapacity) {
|
||||||
super(maxCapacity);
|
super(maxCapacity);
|
||||||
this.recyclerHandle = (Handle<PooledByteBuf<T>>) recyclerHandle;
|
this.recyclerHandle = (Handle<PooledByteBuf<T>>) recyclerHandle;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package io.netty.buffer;
|
package io.netty.buffer;
|
||||||
|
|
||||||
import io.netty.util.Recycler;
|
import io.netty.util.internal.ObjectPool;
|
||||||
|
import io.netty.util.internal.ObjectPool.Handle;
|
||||||
|
import io.netty.util.internal.ObjectPool.ObjectCreator;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -25,12 +27,13 @@ import java.nio.ByteBuffer;
|
|||||||
|
|
||||||
final class PooledDirectByteBuf extends PooledByteBuf<ByteBuffer> {
|
final class PooledDirectByteBuf extends PooledByteBuf<ByteBuffer> {
|
||||||
|
|
||||||
private static final Recycler<PooledDirectByteBuf> RECYCLER = new Recycler<PooledDirectByteBuf>() {
|
private static final ObjectPool<PooledDirectByteBuf> RECYCLER = ObjectPool.newPool(
|
||||||
|
new ObjectCreator<PooledDirectByteBuf>() {
|
||||||
@Override
|
@Override
|
||||||
protected PooledDirectByteBuf newObject(Handle<PooledDirectByteBuf> handle) {
|
public PooledDirectByteBuf newObject(Handle<PooledDirectByteBuf> handle) {
|
||||||
return new PooledDirectByteBuf(handle, 0);
|
return new PooledDirectByteBuf(handle, 0);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
static PooledDirectByteBuf newInstance(int maxCapacity) {
|
static PooledDirectByteBuf newInstance(int maxCapacity) {
|
||||||
PooledDirectByteBuf buf = RECYCLER.get();
|
PooledDirectByteBuf buf = RECYCLER.get();
|
||||||
@ -38,7 +41,7 @@ final class PooledDirectByteBuf extends PooledByteBuf<ByteBuffer> {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PooledDirectByteBuf(Recycler.Handle<PooledDirectByteBuf> recyclerHandle, int maxCapacity) {
|
private PooledDirectByteBuf(Handle<PooledDirectByteBuf> recyclerHandle, int maxCapacity) {
|
||||||
super(recyclerHandle, maxCapacity);
|
super(recyclerHandle, maxCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,8 +17,9 @@
|
|||||||
package io.netty.buffer;
|
package io.netty.buffer;
|
||||||
|
|
||||||
import io.netty.util.ByteProcessor;
|
import io.netty.util.ByteProcessor;
|
||||||
import io.netty.util.Recycler;
|
import io.netty.util.internal.ObjectPool;
|
||||||
import io.netty.util.Recycler.Handle;
|
import io.netty.util.internal.ObjectPool.Handle;
|
||||||
|
import io.netty.util.internal.ObjectPool.ObjectCreator;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -30,12 +31,13 @@ import java.nio.channels.ScatteringByteChannel;
|
|||||||
|
|
||||||
final class PooledDuplicatedByteBuf extends AbstractPooledDerivedByteBuf {
|
final class PooledDuplicatedByteBuf extends AbstractPooledDerivedByteBuf {
|
||||||
|
|
||||||
private static final Recycler<PooledDuplicatedByteBuf> RECYCLER = new Recycler<PooledDuplicatedByteBuf>() {
|
private static final ObjectPool<PooledDuplicatedByteBuf> RECYCLER = ObjectPool.newPool(
|
||||||
|
new ObjectCreator<PooledDuplicatedByteBuf>() {
|
||||||
@Override
|
@Override
|
||||||
protected PooledDuplicatedByteBuf newObject(Handle<PooledDuplicatedByteBuf> handle) {
|
public PooledDuplicatedByteBuf newObject(Handle<PooledDuplicatedByteBuf> handle) {
|
||||||
return new PooledDuplicatedByteBuf(handle);
|
return new PooledDuplicatedByteBuf(handle);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
static PooledDuplicatedByteBuf newInstance(AbstractByteBuf unwrapped, ByteBuf wrapped,
|
static PooledDuplicatedByteBuf newInstance(AbstractByteBuf unwrapped, ByteBuf wrapped,
|
||||||
int readerIndex, int writerIndex) {
|
int readerIndex, int writerIndex) {
|
||||||
|
@ -14,7 +14,9 @@
|
|||||||
|
|
||||||
package io.netty.buffer;
|
package io.netty.buffer;
|
||||||
|
|
||||||
import io.netty.util.Recycler;
|
import io.netty.util.internal.ObjectPool;
|
||||||
|
import io.netty.util.internal.ObjectPool.Handle;
|
||||||
|
import io.netty.util.internal.ObjectPool.ObjectCreator;
|
||||||
import io.netty.util.internal.PlatformDependent;
|
import io.netty.util.internal.PlatformDependent;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -24,12 +26,13 @@ import java.nio.ByteBuffer;
|
|||||||
|
|
||||||
class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
|
class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
|
||||||
|
|
||||||
private static final Recycler<PooledHeapByteBuf> RECYCLER = new Recycler<PooledHeapByteBuf>() {
|
private static final ObjectPool<PooledHeapByteBuf> RECYCLER = ObjectPool.newPool(
|
||||||
|
new ObjectCreator<PooledHeapByteBuf>() {
|
||||||
@Override
|
@Override
|
||||||
protected PooledHeapByteBuf newObject(Handle<PooledHeapByteBuf> handle) {
|
public PooledHeapByteBuf newObject(Handle<PooledHeapByteBuf> handle) {
|
||||||
return new PooledHeapByteBuf(handle, 0);
|
return new PooledHeapByteBuf(handle, 0);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
static PooledHeapByteBuf newInstance(int maxCapacity) {
|
static PooledHeapByteBuf newInstance(int maxCapacity) {
|
||||||
PooledHeapByteBuf buf = RECYCLER.get();
|
PooledHeapByteBuf buf = RECYCLER.get();
|
||||||
@ -37,7 +40,7 @@ class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
PooledHeapByteBuf(Recycler.Handle<? extends PooledHeapByteBuf> recyclerHandle, int maxCapacity) {
|
PooledHeapByteBuf(Handle<? extends PooledHeapByteBuf> recyclerHandle, int maxCapacity) {
|
||||||
super(recyclerHandle, maxCapacity);
|
super(recyclerHandle, maxCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,8 +17,9 @@
|
|||||||
package io.netty.buffer;
|
package io.netty.buffer;
|
||||||
|
|
||||||
import io.netty.util.ByteProcessor;
|
import io.netty.util.ByteProcessor;
|
||||||
import io.netty.util.Recycler;
|
import io.netty.util.internal.ObjectPool;
|
||||||
import io.netty.util.Recycler.Handle;
|
import io.netty.util.internal.ObjectPool.Handle;
|
||||||
|
import io.netty.util.internal.ObjectPool.ObjectCreator;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -32,12 +33,13 @@ import static io.netty.buffer.AbstractUnpooledSlicedByteBuf.checkSliceOutOfBound
|
|||||||
|
|
||||||
final class PooledSlicedByteBuf extends AbstractPooledDerivedByteBuf {
|
final class PooledSlicedByteBuf extends AbstractPooledDerivedByteBuf {
|
||||||
|
|
||||||
private static final Recycler<PooledSlicedByteBuf> RECYCLER = new Recycler<PooledSlicedByteBuf>() {
|
private static final ObjectPool<PooledSlicedByteBuf> RECYCLER = ObjectPool.newPool(
|
||||||
|
new ObjectCreator<PooledSlicedByteBuf>() {
|
||||||
@Override
|
@Override
|
||||||
protected PooledSlicedByteBuf newObject(Handle<PooledSlicedByteBuf> handle) {
|
public PooledSlicedByteBuf newObject(Handle<PooledSlicedByteBuf> handle) {
|
||||||
return new PooledSlicedByteBuf(handle);
|
return new PooledSlicedByteBuf(handle);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
static PooledSlicedByteBuf newInstance(AbstractByteBuf unwrapped, ByteBuf wrapped,
|
static PooledSlicedByteBuf newInstance(AbstractByteBuf unwrapped, ByteBuf wrapped,
|
||||||
int index, int length) {
|
int index, int length) {
|
||||||
|
@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package io.netty.buffer;
|
package io.netty.buffer;
|
||||||
|
|
||||||
import io.netty.util.Recycler;
|
import io.netty.util.internal.ObjectPool;
|
||||||
|
import io.netty.util.internal.ObjectPool.Handle;
|
||||||
|
import io.netty.util.internal.ObjectPool.ObjectCreator;
|
||||||
import io.netty.util.internal.PlatformDependent;
|
import io.netty.util.internal.PlatformDependent;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -25,12 +27,13 @@ import java.io.OutputStream;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
|
final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
|
||||||
private static final Recycler<PooledUnsafeDirectByteBuf> RECYCLER = new Recycler<PooledUnsafeDirectByteBuf>() {
|
private static final ObjectPool<PooledUnsafeDirectByteBuf> RECYCLER = ObjectPool.newPool(
|
||||||
|
new ObjectCreator<PooledUnsafeDirectByteBuf>() {
|
||||||
@Override
|
@Override
|
||||||
protected PooledUnsafeDirectByteBuf newObject(Handle<PooledUnsafeDirectByteBuf> handle) {
|
public PooledUnsafeDirectByteBuf newObject(Handle<PooledUnsafeDirectByteBuf> handle) {
|
||||||
return new PooledUnsafeDirectByteBuf(handle, 0);
|
return new PooledUnsafeDirectByteBuf(handle, 0);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
static PooledUnsafeDirectByteBuf newInstance(int maxCapacity) {
|
static PooledUnsafeDirectByteBuf newInstance(int maxCapacity) {
|
||||||
PooledUnsafeDirectByteBuf buf = RECYCLER.get();
|
PooledUnsafeDirectByteBuf buf = RECYCLER.get();
|
||||||
@ -40,7 +43,7 @@ final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
|
|||||||
|
|
||||||
private long memoryAddress;
|
private long memoryAddress;
|
||||||
|
|
||||||
private PooledUnsafeDirectByteBuf(Recycler.Handle<PooledUnsafeDirectByteBuf> recyclerHandle, int maxCapacity) {
|
private PooledUnsafeDirectByteBuf(Handle<PooledUnsafeDirectByteBuf> recyclerHandle, int maxCapacity) {
|
||||||
super(recyclerHandle, maxCapacity);
|
super(recyclerHandle, maxCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,18 +15,20 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.buffer;
|
package io.netty.buffer;
|
||||||
|
|
||||||
import io.netty.util.Recycler;
|
import io.netty.util.internal.ObjectPool;
|
||||||
import io.netty.util.Recycler.Handle;
|
import io.netty.util.internal.ObjectPool.Handle;
|
||||||
|
import io.netty.util.internal.ObjectPool.ObjectCreator;
|
||||||
import io.netty.util.internal.PlatformDependent;
|
import io.netty.util.internal.PlatformDependent;
|
||||||
|
|
||||||
final class PooledUnsafeHeapByteBuf extends PooledHeapByteBuf {
|
final class PooledUnsafeHeapByteBuf extends PooledHeapByteBuf {
|
||||||
|
|
||||||
private static final Recycler<PooledUnsafeHeapByteBuf> RECYCLER = new Recycler<PooledUnsafeHeapByteBuf>() {
|
private static final ObjectPool<PooledUnsafeHeapByteBuf> RECYCLER = ObjectPool.newPool(
|
||||||
|
new ObjectCreator<PooledUnsafeHeapByteBuf>() {
|
||||||
@Override
|
@Override
|
||||||
protected PooledUnsafeHeapByteBuf newObject(Handle<PooledUnsafeHeapByteBuf> handle) {
|
public PooledUnsafeHeapByteBuf newObject(Handle<PooledUnsafeHeapByteBuf> handle) {
|
||||||
return new PooledUnsafeHeapByteBuf(handle, 0);
|
return new PooledUnsafeHeapByteBuf(handle, 0);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
static PooledUnsafeHeapByteBuf newUnsafeInstance(int maxCapacity) {
|
static PooledUnsafeHeapByteBuf newUnsafeInstance(int maxCapacity) {
|
||||||
PooledUnsafeHeapByteBuf buf = RECYCLER.get();
|
PooledUnsafeHeapByteBuf buf = RECYCLER.get();
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package io.netty.util;
|
package io.netty.util;
|
||||||
|
|
||||||
import io.netty.util.concurrent.FastThreadLocal;
|
import io.netty.util.concurrent.FastThreadLocal;
|
||||||
|
import io.netty.util.internal.ObjectPool;
|
||||||
import io.netty.util.internal.SystemPropertyUtil;
|
import io.netty.util.internal.SystemPropertyUtil;
|
||||||
import io.netty.util.internal.logging.InternalLogger;
|
import io.netty.util.internal.logging.InternalLogger;
|
||||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||||
@ -194,9 +195,7 @@ public abstract class Recycler<T> {
|
|||||||
|
|
||||||
protected abstract T newObject(Handle<T> handle);
|
protected abstract T newObject(Handle<T> handle);
|
||||||
|
|
||||||
public interface Handle<T> {
|
public interface Handle<T> extends ObjectPool.Handle<T> { }
|
||||||
void recycle(T object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static final class DefaultHandle<T> implements Handle<T> {
|
static final class DefaultHandle<T> implements Handle<T> {
|
||||||
private int lastRecycledId;
|
private int lastRecycledId;
|
||||||
|
89
common/src/main/java/io/netty/util/internal/ObjectPool.java
Normal file
89
common/src/main/java/io/netty/util/internal/ObjectPool.java
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.util.internal;
|
||||||
|
|
||||||
|
import io.netty.util.Recycler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Light-weight object pool.
|
||||||
|
*
|
||||||
|
* @param <T> the type of the pooled object
|
||||||
|
*/
|
||||||
|
public abstract class ObjectPool<T> {
|
||||||
|
|
||||||
|
ObjectPool() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a {@link Object} from the {@link ObjectPool}. The returned {@link Object} may be created via
|
||||||
|
* {@link ObjectCreator#newObject(Handle)} if no pooled {@link Object} is ready to be reused.
|
||||||
|
*/
|
||||||
|
public abstract T get();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle for an pooled {@link Object} that will be used to notify the {@link ObjectPool} once it can
|
||||||
|
* reuse the pooled {@link Object} again.
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
|
public interface Handle<T> {
|
||||||
|
/**
|
||||||
|
* Recycle the {@link Object} if possible and so make it ready to be reused.
|
||||||
|
*/
|
||||||
|
void recycle(T self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Object which references the given {@link Handle} and calls {@link Handle#recycle(Object)} once
|
||||||
|
* it can be re-used.
|
||||||
|
*
|
||||||
|
* @param <T> the type of the pooled object
|
||||||
|
*/
|
||||||
|
public interface ObjectCreator<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an returns a new {@link Object} that can be used and later recycled via
|
||||||
|
* {@link Handle#recycle(Object)}.
|
||||||
|
*/
|
||||||
|
T newObject(Handle<T> handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link ObjectPool} which will use the given {@link ObjectCreator} to create the {@link Object}
|
||||||
|
* that should be pooled.
|
||||||
|
*/
|
||||||
|
public static <T> ObjectPool<T> newPool(final ObjectCreator<T> creator) {
|
||||||
|
ObjectUtil.checkNotNull(creator, "creator");
|
||||||
|
|
||||||
|
return new RecyclerObjectPool<T>(creator);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class RecyclerObjectPool<T> extends ObjectPool<T> {
|
||||||
|
private final Recycler<T> recycler;
|
||||||
|
|
||||||
|
RecyclerObjectPool(final ObjectCreator<T> creator) {
|
||||||
|
recycler = new Recycler<T>() {
|
||||||
|
@Override
|
||||||
|
protected T newObject(Handle<T> handle) {
|
||||||
|
return creator.newObject(handle);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T get() {
|
||||||
|
return recycler.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -15,20 +15,21 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.util.internal;
|
package io.netty.util.internal;
|
||||||
|
|
||||||
import io.netty.util.Recycler;
|
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import io.netty.util.concurrent.Promise;
|
import io.netty.util.concurrent.Promise;
|
||||||
|
import io.netty.util.internal.ObjectPool.Handle;
|
||||||
|
import io.netty.util.internal.ObjectPool.ObjectCreator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some pending write which should be picked up later.
|
* Some pending write which should be picked up later.
|
||||||
*/
|
*/
|
||||||
public final class PendingWrite {
|
public final class PendingWrite {
|
||||||
private static final Recycler<PendingWrite> RECYCLER = new Recycler<PendingWrite>() {
|
private static final ObjectPool<PendingWrite> RECYCLER = ObjectPool.newPool(new ObjectCreator<PendingWrite>() {
|
||||||
@Override
|
@Override
|
||||||
protected PendingWrite newObject(Handle<PendingWrite> handle) {
|
public PendingWrite newObject(Handle<PendingWrite> handle) {
|
||||||
return new PendingWrite(handle);
|
return new PendingWrite(handle);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new empty {@link RecyclableArrayList} instance
|
* Create a new empty {@link RecyclableArrayList} instance
|
||||||
@ -40,11 +41,11 @@ public final class PendingWrite {
|
|||||||
return pending;
|
return pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Recycler.Handle<PendingWrite> handle;
|
private final Handle<PendingWrite> handle;
|
||||||
private Object msg;
|
private Object msg;
|
||||||
private Promise<Void> promise;
|
private Promise<Void> promise;
|
||||||
|
|
||||||
private PendingWrite(Recycler.Handle<PendingWrite> handle) {
|
private PendingWrite(Handle<PendingWrite> handle) {
|
||||||
this.handle = handle;
|
this.handle = handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
package io.netty.util.internal;
|
package io.netty.util.internal;
|
||||||
|
|
||||||
import io.netty.util.Recycler;
|
import io.netty.util.internal.ObjectPool.Handle;
|
||||||
import io.netty.util.Recycler.Handle;
|
import io.netty.util.internal.ObjectPool.ObjectCreator;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -33,12 +33,13 @@ public final class RecyclableArrayList extends ArrayList<Object> {
|
|||||||
|
|
||||||
private static final int DEFAULT_INITIAL_CAPACITY = 8;
|
private static final int DEFAULT_INITIAL_CAPACITY = 8;
|
||||||
|
|
||||||
private static final Recycler<RecyclableArrayList> RECYCLER = new Recycler<RecyclableArrayList>() {
|
private static final ObjectPool<RecyclableArrayList> RECYCLER = ObjectPool.newPool(
|
||||||
|
new ObjectCreator<RecyclableArrayList>() {
|
||||||
@Override
|
@Override
|
||||||
protected RecyclableArrayList newObject(Handle<RecyclableArrayList> handle) {
|
public RecyclableArrayList newObject(Handle<RecyclableArrayList> handle) {
|
||||||
return new RecyclableArrayList(handle);
|
return new RecyclableArrayList(handle);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
private boolean insertSinceRecycled;
|
private boolean insertSinceRecycled;
|
||||||
|
|
||||||
|
@ -24,9 +24,10 @@ import io.netty.channel.ChannelHandler;
|
|||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||||
import io.netty.handler.codec.MessageToByteEncoder;
|
import io.netty.handler.codec.MessageToByteEncoder;
|
||||||
import io.netty.util.Recycler;
|
|
||||||
import io.netty.util.Recycler.Handle;
|
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
|
import io.netty.util.internal.ObjectPool;
|
||||||
|
import io.netty.util.internal.ObjectPool.Handle;
|
||||||
|
import io.netty.util.internal.ObjectPool.ObjectCreator;
|
||||||
import io.netty.util.internal.logging.InternalLogger;
|
import io.netty.util.internal.logging.InternalLogger;
|
||||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||||
|
|
||||||
@ -217,12 +218,13 @@ public class FlowControlHandler extends ChannelDuplexHandler {
|
|||||||
*/
|
*/
|
||||||
private static final int DEFAULT_NUM_ELEMENTS = 2;
|
private static final int DEFAULT_NUM_ELEMENTS = 2;
|
||||||
|
|
||||||
private static final Recycler<RecyclableArrayDeque> RECYCLER = new Recycler<RecyclableArrayDeque>() {
|
private static final ObjectPool<RecyclableArrayDeque> RECYCLER = ObjectPool.newPool(
|
||||||
|
new ObjectCreator<RecyclableArrayDeque>() {
|
||||||
@Override
|
@Override
|
||||||
protected RecyclableArrayDeque newObject(Handle<RecyclableArrayDeque> handle) {
|
public RecyclableArrayDeque newObject(Handle<RecyclableArrayDeque> handle) {
|
||||||
return new RecyclableArrayDeque(DEFAULT_NUM_ELEMENTS, handle);
|
return new RecyclableArrayDeque(DEFAULT_NUM_ELEMENTS, handle);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
public static RecyclableArrayDeque newInstance() {
|
public static RecyclableArrayDeque newInstance() {
|
||||||
return RECYCLER.get();
|
return RECYCLER.get();
|
||||||
|
@ -18,11 +18,13 @@ package io.netty.channel;
|
|||||||
import io.netty.buffer.ByteBufAllocator;
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
import io.netty.util.Attribute;
|
import io.netty.util.Attribute;
|
||||||
import io.netty.util.AttributeKey;
|
import io.netty.util.AttributeKey;
|
||||||
import io.netty.util.Recycler;
|
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import io.netty.util.ResourceLeakHint;
|
import io.netty.util.ResourceLeakHint;
|
||||||
import io.netty.util.concurrent.EventExecutor;
|
import io.netty.util.concurrent.EventExecutor;
|
||||||
import io.netty.util.concurrent.OrderedEventExecutor;
|
import io.netty.util.concurrent.OrderedEventExecutor;
|
||||||
|
import io.netty.util.internal.ObjectPool;
|
||||||
|
import io.netty.util.internal.ObjectPool.Handle;
|
||||||
|
import io.netty.util.internal.ObjectPool.ObjectCreator;
|
||||||
import io.netty.util.internal.PromiseNotificationUtil;
|
import io.netty.util.internal.PromiseNotificationUtil;
|
||||||
import io.netty.util.internal.ThrowableUtil;
|
import io.netty.util.internal.ThrowableUtil;
|
||||||
import io.netty.util.internal.ObjectUtil;
|
import io.netty.util.internal.ObjectUtil;
|
||||||
@ -1041,15 +1043,15 @@ abstract class AbstractChannelHandlerContext implements ChannelHandlerContext, R
|
|||||||
private static final int WRITE_TASK_OVERHEAD =
|
private static final int WRITE_TASK_OVERHEAD =
|
||||||
SystemPropertyUtil.getInt("io.netty.transport.writeTaskSizeOverhead", 48);
|
SystemPropertyUtil.getInt("io.netty.transport.writeTaskSizeOverhead", 48);
|
||||||
|
|
||||||
private final Recycler.Handle<AbstractWriteTask> handle;
|
private final Handle<AbstractWriteTask> handle;
|
||||||
private AbstractChannelHandlerContext ctx;
|
private AbstractChannelHandlerContext ctx;
|
||||||
private Object msg;
|
private Object msg;
|
||||||
private ChannelPromise promise;
|
private ChannelPromise promise;
|
||||||
private int size;
|
private int size;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private AbstractWriteTask(Recycler.Handle<? extends AbstractWriteTask> handle) {
|
private AbstractWriteTask(Handle<? extends AbstractWriteTask> handle) {
|
||||||
this.handle = (Recycler.Handle<AbstractWriteTask>) handle;
|
this.handle = (Handle<AbstractWriteTask>) handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void init(AbstractWriteTask task, AbstractChannelHandlerContext ctx,
|
protected static void init(AbstractWriteTask task, AbstractChannelHandlerContext ctx,
|
||||||
@ -1105,12 +1107,12 @@ abstract class AbstractChannelHandlerContext implements ChannelHandlerContext, R
|
|||||||
|
|
||||||
static final class WriteTask extends AbstractWriteTask implements SingleThreadEventLoop.NonWakeupRunnable {
|
static final class WriteTask extends AbstractWriteTask implements SingleThreadEventLoop.NonWakeupRunnable {
|
||||||
|
|
||||||
private static final Recycler<WriteTask> RECYCLER = new Recycler<WriteTask>() {
|
private static final ObjectPool<WriteTask> RECYCLER = ObjectPool.newPool(new ObjectCreator<WriteTask>() {
|
||||||
@Override
|
@Override
|
||||||
protected WriteTask newObject(Handle<WriteTask> handle) {
|
public WriteTask newObject(Handle<WriteTask> handle) {
|
||||||
return new WriteTask(handle);
|
return new WriteTask(handle);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
static WriteTask newInstance(
|
static WriteTask newInstance(
|
||||||
AbstractChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
|
AbstractChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
|
||||||
@ -1119,19 +1121,20 @@ abstract class AbstractChannelHandlerContext implements ChannelHandlerContext, R
|
|||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
private WriteTask(Recycler.Handle<WriteTask> handle) {
|
private WriteTask(Handle<WriteTask> handle) {
|
||||||
super(handle);
|
super(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class WriteAndFlushTask extends AbstractWriteTask {
|
static final class WriteAndFlushTask extends AbstractWriteTask {
|
||||||
|
|
||||||
private static final Recycler<WriteAndFlushTask> RECYCLER = new Recycler<WriteAndFlushTask>() {
|
private static final ObjectPool<WriteAndFlushTask> RECYCLER = ObjectPool.newPool(
|
||||||
|
new ObjectCreator<WriteAndFlushTask>() {
|
||||||
@Override
|
@Override
|
||||||
protected WriteAndFlushTask newObject(Handle<WriteAndFlushTask> handle) {
|
public WriteAndFlushTask newObject(Handle<WriteAndFlushTask> handle) {
|
||||||
return new WriteAndFlushTask(handle);
|
return new WriteAndFlushTask(handle);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
static WriteAndFlushTask newInstance(
|
static WriteAndFlushTask newInstance(
|
||||||
AbstractChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
|
AbstractChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
|
||||||
@ -1140,7 +1143,7 @@ abstract class AbstractChannelHandlerContext implements ChannelHandlerContext, R
|
|||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
private WriteAndFlushTask(Recycler.Handle<WriteAndFlushTask> handle) {
|
private WriteAndFlushTask(Handle<WriteAndFlushTask> handle) {
|
||||||
super(handle);
|
super(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,11 +19,12 @@ import io.netty.buffer.ByteBuf;
|
|||||||
import io.netty.buffer.ByteBufHolder;
|
import io.netty.buffer.ByteBufHolder;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||||
import io.netty.util.Recycler;
|
|
||||||
import io.netty.util.Recycler.Handle;
|
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import io.netty.util.concurrent.FastThreadLocal;
|
import io.netty.util.concurrent.FastThreadLocal;
|
||||||
import io.netty.util.internal.InternalThreadLocalMap;
|
import io.netty.util.internal.InternalThreadLocalMap;
|
||||||
|
import io.netty.util.internal.ObjectPool;
|
||||||
|
import io.netty.util.internal.ObjectPool.Handle;
|
||||||
|
import io.netty.util.internal.ObjectPool.ObjectCreator;
|
||||||
import io.netty.util.internal.PromiseNotificationUtil;
|
import io.netty.util.internal.PromiseNotificationUtil;
|
||||||
import io.netty.util.internal.SystemPropertyUtil;
|
import io.netty.util.internal.SystemPropertyUtil;
|
||||||
import io.netty.util.internal.logging.InternalLogger;
|
import io.netty.util.internal.logging.InternalLogger;
|
||||||
@ -798,12 +799,12 @@ public final class ChannelOutboundBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static final class Entry {
|
static final class Entry {
|
||||||
private static final Recycler<Entry> RECYCLER = new Recycler<Entry>() {
|
private static final ObjectPool<Entry> RECYCLER = ObjectPool.newPool(new ObjectCreator<Entry>() {
|
||||||
@Override
|
@Override
|
||||||
protected Entry newObject(Handle<Entry> handle) {
|
public Entry newObject(Handle<Entry> handle) {
|
||||||
return new Entry(handle);
|
return new Entry(handle);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
private final Handle<Entry> handle;
|
private final Handle<Entry> handle;
|
||||||
Entry next;
|
Entry next;
|
||||||
|
@ -15,9 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.channel;
|
package io.netty.channel;
|
||||||
|
|
||||||
import io.netty.util.Recycler;
|
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import io.netty.util.concurrent.PromiseCombiner;
|
import io.netty.util.concurrent.PromiseCombiner;
|
||||||
|
import io.netty.util.internal.ObjectPool;
|
||||||
|
import io.netty.util.internal.ObjectPool.ObjectCreator;
|
||||||
import io.netty.util.internal.SystemPropertyUtil;
|
import io.netty.util.internal.SystemPropertyUtil;
|
||||||
import io.netty.util.internal.logging.InternalLogger;
|
import io.netty.util.internal.logging.InternalLogger;
|
||||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||||
@ -291,20 +292,20 @@ public final class PendingWriteQueue {
|
|||||||
* Holds all meta-data and construct the linked-list structure.
|
* Holds all meta-data and construct the linked-list structure.
|
||||||
*/
|
*/
|
||||||
static final class PendingWrite {
|
static final class PendingWrite {
|
||||||
private static final Recycler<PendingWrite> RECYCLER = new Recycler<PendingWrite>() {
|
private static final ObjectPool<PendingWrite> RECYCLER = ObjectPool.newPool(new ObjectCreator<PendingWrite>() {
|
||||||
@Override
|
@Override
|
||||||
protected PendingWrite newObject(Handle<PendingWrite> handle) {
|
public PendingWrite newObject(ObjectPool.Handle<PendingWrite> handle) {
|
||||||
return new PendingWrite(handle);
|
return new PendingWrite(handle);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
private final Recycler.Handle<PendingWrite> handle;
|
private final ObjectPool.Handle<PendingWrite> handle;
|
||||||
private PendingWrite next;
|
private PendingWrite next;
|
||||||
private long size;
|
private long size;
|
||||||
private ChannelPromise promise;
|
private ChannelPromise promise;
|
||||||
private Object msg;
|
private Object msg;
|
||||||
|
|
||||||
private PendingWrite(Recycler.Handle<PendingWrite> handle) {
|
private PendingWrite(ObjectPool.Handle<PendingWrite> handle) {
|
||||||
this.handle = handle;
|
this.handle = handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user