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:
Norman Maurer 2019-10-26 00:34:30 -07:00 committed by GitHub
parent aa3c57508b
commit 6c061abc49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 205 additions and 91 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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);
} }
}; });
} }
} }

View File

@ -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;
} }

View File

@ -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);
} }

View File

@ -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) {

View File

@ -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);
} }

View File

@ -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) {

View File

@ -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);
} }

View File

@ -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();

View File

@ -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;

View 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();
}
}
}

View File

@ -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;
} }

View File

@ -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;

View File

@ -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();

View File

@ -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);
} }

View File

@ -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;

View File

@ -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;
} }