From 6c061abc4905e0a7379d9ede5677409df32a9489 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Sat, 26 Oct 2019 00:34:30 -0700 Subject: [PATCH] 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 --- .../buffer/AbstractPooledDerivedByteBuf.java | 2 +- .../java/io/netty/buffer/ByteBufUtil.java | 20 +++-- .../java/io/netty/buffer/PoolThreadCache.java | 11 +-- .../java/io/netty/buffer/PooledByteBuf.java | 7 +- .../io/netty/buffer/PooledDirectByteBuf.java | 13 +-- .../netty/buffer/PooledDuplicatedByteBuf.java | 12 +-- .../io/netty/buffer/PooledHeapByteBuf.java | 13 +-- .../io/netty/buffer/PooledSlicedByteBuf.java | 12 +-- .../buffer/PooledUnsafeDirectByteBuf.java | 13 +-- .../netty/buffer/PooledUnsafeHeapByteBuf.java | 12 +-- .../src/main/java/io/netty/util/Recycler.java | 5 +- .../io/netty/util/internal/ObjectPool.java | 89 +++++++++++++++++++ .../io/netty/util/internal/PendingWrite.java | 13 +-- .../util/internal/RecyclableArrayList.java | 11 +-- .../handler/flow/FlowControlHandler.java | 12 +-- .../AbstractChannelHandlerContext.java | 27 +++--- .../netty/channel/ChannelOutboundBuffer.java | 11 +-- .../io/netty/channel/PendingWriteQueue.java | 13 +-- 18 files changed, 205 insertions(+), 91 deletions(-) create mode 100644 common/src/main/java/io/netty/util/internal/ObjectPool.java diff --git a/buffer/src/main/java/io/netty/buffer/AbstractPooledDerivedByteBuf.java b/buffer/src/main/java/io/netty/buffer/AbstractPooledDerivedByteBuf.java index bc1b9c93d2..b106f57887 100644 --- a/buffer/src/main/java/io/netty/buffer/AbstractPooledDerivedByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/AbstractPooledDerivedByteBuf.java @@ -16,8 +16,8 @@ package io.netty.buffer; -import io.netty.util.Recycler.Handle; import io.netty.util.ReferenceCounted; +import io.netty.util.internal.ObjectPool.Handle; import java.nio.ByteBuffer; import java.nio.ByteOrder; diff --git a/buffer/src/main/java/io/netty/buffer/ByteBufUtil.java b/buffer/src/main/java/io/netty/buffer/ByteBufUtil.java index 925d5c7721..9aed1664c2 100644 --- a/buffer/src/main/java/io/netty/buffer/ByteBufUtil.java +++ b/buffer/src/main/java/io/netty/buffer/ByteBufUtil.java @@ -18,10 +18,11 @@ package io.netty.buffer; import io.netty.util.AsciiString; import io.netty.util.ByteProcessor; 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.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.StringUtil; import io.netty.util.internal.SystemPropertyUtil; @@ -1171,13 +1172,13 @@ public final class ByteBufUtil { static final class ThreadLocalUnsafeDirectByteBuf extends UnpooledUnsafeDirectByteBuf { - private static final Recycler RECYCLER = - new Recycler() { + private static final ObjectPool RECYCLER = + ObjectPool.newPool(new ObjectCreator() { @Override - protected ThreadLocalUnsafeDirectByteBuf newObject(Handle handle) { + public ThreadLocalUnsafeDirectByteBuf newObject(Handle handle) { return new ThreadLocalUnsafeDirectByteBuf(handle); } - }; + }); static ThreadLocalUnsafeDirectByteBuf newInstance() { ThreadLocalUnsafeDirectByteBuf buf = RECYCLER.get(); @@ -1205,12 +1206,13 @@ public final class ByteBufUtil { static final class ThreadLocalDirectByteBuf extends UnpooledDirectByteBuf { - private static final Recycler RECYCLER = new Recycler() { + private static final ObjectPool RECYCLER = ObjectPool.newPool( + new ObjectCreator() { @Override - protected ThreadLocalDirectByteBuf newObject(Handle handle) { + public ThreadLocalDirectByteBuf newObject(Handle handle) { return new ThreadLocalDirectByteBuf(handle); } - }; + }); static ThreadLocalDirectByteBuf newInstance() { ThreadLocalDirectByteBuf buf = RECYCLER.get(); diff --git a/buffer/src/main/java/io/netty/buffer/PoolThreadCache.java b/buffer/src/main/java/io/netty/buffer/PoolThreadCache.java index cb638f1a1d..c1bf7e6d07 100644 --- a/buffer/src/main/java/io/netty/buffer/PoolThreadCache.java +++ b/buffer/src/main/java/io/netty/buffer/PoolThreadCache.java @@ -20,9 +20,10 @@ package io.netty.buffer; import static io.netty.util.internal.ObjectUtil.checkPositiveOrZero; 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.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.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; @@ -492,12 +493,12 @@ final class PoolThreadCache { } @SuppressWarnings("rawtypes") - private static final Recycler RECYCLER = new Recycler() { + private static final ObjectPool RECYCLER = ObjectPool.newPool(new ObjectCreator() { @SuppressWarnings("unchecked") @Override - protected Entry newObject(Handle handle) { + public Entry newObject(Handle handle) { return new Entry(handle); } - }; + }); } } diff --git a/buffer/src/main/java/io/netty/buffer/PooledByteBuf.java b/buffer/src/main/java/io/netty/buffer/PooledByteBuf.java index 5b984eb7e7..8af5fac8a9 100644 --- a/buffer/src/main/java/io/netty/buffer/PooledByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/PooledByteBuf.java @@ -16,8 +16,7 @@ package io.netty.buffer; -import io.netty.util.Recycler; -import io.netty.util.Recycler.Handle; +import io.netty.util.internal.ObjectPool.Handle; import java.io.IOException; import java.nio.ByteBuffer; @@ -29,7 +28,7 @@ import java.nio.channels.ScatteringByteChannel; abstract class PooledByteBuf extends AbstractReferenceCountedByteBuf { - private final Recycler.Handle> recyclerHandle; + private final Handle> recyclerHandle; protected PoolChunk chunk; protected long handle; @@ -42,7 +41,7 @@ abstract class PooledByteBuf extends AbstractReferenceCountedByteBuf { private ByteBufAllocator allocator; @SuppressWarnings("unchecked") - protected PooledByteBuf(Recycler.Handle> recyclerHandle, int maxCapacity) { + protected PooledByteBuf(Handle> recyclerHandle, int maxCapacity) { super(maxCapacity); this.recyclerHandle = (Handle>) recyclerHandle; } diff --git a/buffer/src/main/java/io/netty/buffer/PooledDirectByteBuf.java b/buffer/src/main/java/io/netty/buffer/PooledDirectByteBuf.java index f05ab4bdb9..dee7fe6774 100644 --- a/buffer/src/main/java/io/netty/buffer/PooledDirectByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/PooledDirectByteBuf.java @@ -16,7 +16,9 @@ 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.InputStream; @@ -25,12 +27,13 @@ import java.nio.ByteBuffer; final class PooledDirectByteBuf extends PooledByteBuf { - private static final Recycler RECYCLER = new Recycler() { + private static final ObjectPool RECYCLER = ObjectPool.newPool( + new ObjectCreator() { @Override - protected PooledDirectByteBuf newObject(Handle handle) { + public PooledDirectByteBuf newObject(Handle handle) { return new PooledDirectByteBuf(handle, 0); } - }; + }); static PooledDirectByteBuf newInstance(int maxCapacity) { PooledDirectByteBuf buf = RECYCLER.get(); @@ -38,7 +41,7 @@ final class PooledDirectByteBuf extends PooledByteBuf { return buf; } - private PooledDirectByteBuf(Recycler.Handle recyclerHandle, int maxCapacity) { + private PooledDirectByteBuf(Handle recyclerHandle, int maxCapacity) { super(recyclerHandle, maxCapacity); } diff --git a/buffer/src/main/java/io/netty/buffer/PooledDuplicatedByteBuf.java b/buffer/src/main/java/io/netty/buffer/PooledDuplicatedByteBuf.java index 1260f4e31f..89646e2dfe 100644 --- a/buffer/src/main/java/io/netty/buffer/PooledDuplicatedByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/PooledDuplicatedByteBuf.java @@ -17,8 +17,9 @@ package io.netty.buffer; import io.netty.util.ByteProcessor; -import io.netty.util.Recycler; -import io.netty.util.Recycler.Handle; +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.InputStream; @@ -30,12 +31,13 @@ import java.nio.channels.ScatteringByteChannel; final class PooledDuplicatedByteBuf extends AbstractPooledDerivedByteBuf { - private static final Recycler RECYCLER = new Recycler() { + private static final ObjectPool RECYCLER = ObjectPool.newPool( + new ObjectCreator() { @Override - protected PooledDuplicatedByteBuf newObject(Handle handle) { + public PooledDuplicatedByteBuf newObject(Handle handle) { return new PooledDuplicatedByteBuf(handle); } - }; + }); static PooledDuplicatedByteBuf newInstance(AbstractByteBuf unwrapped, ByteBuf wrapped, int readerIndex, int writerIndex) { diff --git a/buffer/src/main/java/io/netty/buffer/PooledHeapByteBuf.java b/buffer/src/main/java/io/netty/buffer/PooledHeapByteBuf.java index bc740c0168..f271e6c050 100644 --- a/buffer/src/main/java/io/netty/buffer/PooledHeapByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/PooledHeapByteBuf.java @@ -14,7 +14,9 @@ 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 java.io.IOException; @@ -24,12 +26,13 @@ import java.nio.ByteBuffer; class PooledHeapByteBuf extends PooledByteBuf { - private static final Recycler RECYCLER = new Recycler() { + private static final ObjectPool RECYCLER = ObjectPool.newPool( + new ObjectCreator() { @Override - protected PooledHeapByteBuf newObject(Handle handle) { + public PooledHeapByteBuf newObject(Handle handle) { return new PooledHeapByteBuf(handle, 0); } - }; + }); static PooledHeapByteBuf newInstance(int maxCapacity) { PooledHeapByteBuf buf = RECYCLER.get(); @@ -37,7 +40,7 @@ class PooledHeapByteBuf extends PooledByteBuf { return buf; } - PooledHeapByteBuf(Recycler.Handle recyclerHandle, int maxCapacity) { + PooledHeapByteBuf(Handle recyclerHandle, int maxCapacity) { super(recyclerHandle, maxCapacity); } diff --git a/buffer/src/main/java/io/netty/buffer/PooledSlicedByteBuf.java b/buffer/src/main/java/io/netty/buffer/PooledSlicedByteBuf.java index 44051881ab..256a5f338b 100644 --- a/buffer/src/main/java/io/netty/buffer/PooledSlicedByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/PooledSlicedByteBuf.java @@ -17,8 +17,9 @@ package io.netty.buffer; import io.netty.util.ByteProcessor; -import io.netty.util.Recycler; -import io.netty.util.Recycler.Handle; +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.InputStream; @@ -32,12 +33,13 @@ import static io.netty.buffer.AbstractUnpooledSlicedByteBuf.checkSliceOutOfBound final class PooledSlicedByteBuf extends AbstractPooledDerivedByteBuf { - private static final Recycler RECYCLER = new Recycler() { + private static final ObjectPool RECYCLER = ObjectPool.newPool( + new ObjectCreator() { @Override - protected PooledSlicedByteBuf newObject(Handle handle) { + public PooledSlicedByteBuf newObject(Handle handle) { return new PooledSlicedByteBuf(handle); } - }; + }); static PooledSlicedByteBuf newInstance(AbstractByteBuf unwrapped, ByteBuf wrapped, int index, int length) { diff --git a/buffer/src/main/java/io/netty/buffer/PooledUnsafeDirectByteBuf.java b/buffer/src/main/java/io/netty/buffer/PooledUnsafeDirectByteBuf.java index e5a335d6d9..fd7e27d214 100644 --- a/buffer/src/main/java/io/netty/buffer/PooledUnsafeDirectByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/PooledUnsafeDirectByteBuf.java @@ -16,7 +16,9 @@ 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 java.io.IOException; @@ -25,12 +27,13 @@ import java.io.OutputStream; import java.nio.ByteBuffer; final class PooledUnsafeDirectByteBuf extends PooledByteBuf { - private static final Recycler RECYCLER = new Recycler() { + private static final ObjectPool RECYCLER = ObjectPool.newPool( + new ObjectCreator() { @Override - protected PooledUnsafeDirectByteBuf newObject(Handle handle) { + public PooledUnsafeDirectByteBuf newObject(Handle handle) { return new PooledUnsafeDirectByteBuf(handle, 0); } - }; + }); static PooledUnsafeDirectByteBuf newInstance(int maxCapacity) { PooledUnsafeDirectByteBuf buf = RECYCLER.get(); @@ -40,7 +43,7 @@ final class PooledUnsafeDirectByteBuf extends PooledByteBuf { private long memoryAddress; - private PooledUnsafeDirectByteBuf(Recycler.Handle recyclerHandle, int maxCapacity) { + private PooledUnsafeDirectByteBuf(Handle recyclerHandle, int maxCapacity) { super(recyclerHandle, maxCapacity); } diff --git a/buffer/src/main/java/io/netty/buffer/PooledUnsafeHeapByteBuf.java b/buffer/src/main/java/io/netty/buffer/PooledUnsafeHeapByteBuf.java index a644450f5c..88273af4e4 100644 --- a/buffer/src/main/java/io/netty/buffer/PooledUnsafeHeapByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/PooledUnsafeHeapByteBuf.java @@ -15,18 +15,20 @@ */ package io.netty.buffer; -import io.netty.util.Recycler; -import io.netty.util.Recycler.Handle; +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; final class PooledUnsafeHeapByteBuf extends PooledHeapByteBuf { - private static final Recycler RECYCLER = new Recycler() { + private static final ObjectPool RECYCLER = ObjectPool.newPool( + new ObjectCreator() { @Override - protected PooledUnsafeHeapByteBuf newObject(Handle handle) { + public PooledUnsafeHeapByteBuf newObject(Handle handle) { return new PooledUnsafeHeapByteBuf(handle, 0); } - }; + }); static PooledUnsafeHeapByteBuf newUnsafeInstance(int maxCapacity) { PooledUnsafeHeapByteBuf buf = RECYCLER.get(); diff --git a/common/src/main/java/io/netty/util/Recycler.java b/common/src/main/java/io/netty/util/Recycler.java index 814d8e2109..d798a86afc 100644 --- a/common/src/main/java/io/netty/util/Recycler.java +++ b/common/src/main/java/io/netty/util/Recycler.java @@ -17,6 +17,7 @@ package io.netty.util; import io.netty.util.concurrent.FastThreadLocal; +import io.netty.util.internal.ObjectPool; import io.netty.util.internal.SystemPropertyUtil; import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; @@ -194,9 +195,7 @@ public abstract class Recycler { protected abstract T newObject(Handle handle); - public interface Handle { - void recycle(T object); - } + public interface Handle extends ObjectPool.Handle { } static final class DefaultHandle implements Handle { private int lastRecycledId; diff --git a/common/src/main/java/io/netty/util/internal/ObjectPool.java b/common/src/main/java/io/netty/util/internal/ObjectPool.java new file mode 100644 index 0000000000..38ab06605e --- /dev/null +++ b/common/src/main/java/io/netty/util/internal/ObjectPool.java @@ -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 the type of the pooled object + */ +public abstract class ObjectPool { + + 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 + */ + public interface Handle { + /** + * 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 the type of the pooled object + */ + public interface ObjectCreator { + + /** + * Creates an returns a new {@link Object} that can be used and later recycled via + * {@link Handle#recycle(Object)}. + */ + T newObject(Handle handle); + } + + /** + * Creates a new {@link ObjectPool} which will use the given {@link ObjectCreator} to create the {@link Object} + * that should be pooled. + */ + public static ObjectPool newPool(final ObjectCreator creator) { + ObjectUtil.checkNotNull(creator, "creator"); + + return new RecyclerObjectPool(creator); + } + + private static final class RecyclerObjectPool extends ObjectPool { + private final Recycler recycler; + + RecyclerObjectPool(final ObjectCreator creator) { + recycler = new Recycler() { + @Override + protected T newObject(Handle handle) { + return creator.newObject(handle); + } + }; + } + + @Override + public T get() { + return recycler.get(); + } + } +} diff --git a/common/src/main/java/io/netty/util/internal/PendingWrite.java b/common/src/main/java/io/netty/util/internal/PendingWrite.java index 6f27cf52db..f84826caf4 100644 --- a/common/src/main/java/io/netty/util/internal/PendingWrite.java +++ b/common/src/main/java/io/netty/util/internal/PendingWrite.java @@ -15,20 +15,21 @@ */ package io.netty.util.internal; -import io.netty.util.Recycler; import io.netty.util.ReferenceCountUtil; 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. */ public final class PendingWrite { - private static final Recycler RECYCLER = new Recycler() { + private static final ObjectPool RECYCLER = ObjectPool.newPool(new ObjectCreator() { @Override - protected PendingWrite newObject(Handle handle) { + public PendingWrite newObject(Handle handle) { return new PendingWrite(handle); } - }; + }); /** * Create a new empty {@link RecyclableArrayList} instance @@ -40,11 +41,11 @@ public final class PendingWrite { return pending; } - private final Recycler.Handle handle; + private final Handle handle; private Object msg; private Promise promise; - private PendingWrite(Recycler.Handle handle) { + private PendingWrite(Handle handle) { this.handle = handle; } diff --git a/common/src/main/java/io/netty/util/internal/RecyclableArrayList.java b/common/src/main/java/io/netty/util/internal/RecyclableArrayList.java index bf98f22a1a..ab0477dc6d 100644 --- a/common/src/main/java/io/netty/util/internal/RecyclableArrayList.java +++ b/common/src/main/java/io/netty/util/internal/RecyclableArrayList.java @@ -16,8 +16,8 @@ package io.netty.util.internal; -import io.netty.util.Recycler; -import io.netty.util.Recycler.Handle; +import io.netty.util.internal.ObjectPool.Handle; +import io.netty.util.internal.ObjectPool.ObjectCreator; import java.util.ArrayList; import java.util.Collection; @@ -33,12 +33,13 @@ public final class RecyclableArrayList extends ArrayList { private static final int DEFAULT_INITIAL_CAPACITY = 8; - private static final Recycler RECYCLER = new Recycler() { + private static final ObjectPool RECYCLER = ObjectPool.newPool( + new ObjectCreator() { @Override - protected RecyclableArrayList newObject(Handle handle) { + public RecyclableArrayList newObject(Handle handle) { return new RecyclableArrayList(handle); } - }; + }); private boolean insertSinceRecycled; diff --git a/handler/src/main/java/io/netty/handler/flow/FlowControlHandler.java b/handler/src/main/java/io/netty/handler/flow/FlowControlHandler.java index 3ee0c12118..c79c36a580 100644 --- a/handler/src/main/java/io/netty/handler/flow/FlowControlHandler.java +++ b/handler/src/main/java/io/netty/handler/flow/FlowControlHandler.java @@ -24,9 +24,10 @@ import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; 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.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.InternalLoggerFactory; @@ -217,12 +218,13 @@ public class FlowControlHandler extends ChannelDuplexHandler { */ private static final int DEFAULT_NUM_ELEMENTS = 2; - private static final Recycler RECYCLER = new Recycler() { + private static final ObjectPool RECYCLER = ObjectPool.newPool( + new ObjectCreator() { @Override - protected RecyclableArrayDeque newObject(Handle handle) { + public RecyclableArrayDeque newObject(Handle handle) { return new RecyclableArrayDeque(DEFAULT_NUM_ELEMENTS, handle); } - }; + }); public static RecyclableArrayDeque newInstance() { return RECYCLER.get(); diff --git a/transport/src/main/java/io/netty/channel/AbstractChannelHandlerContext.java b/transport/src/main/java/io/netty/channel/AbstractChannelHandlerContext.java index 1ba26fc44c..510dfd4f15 100644 --- a/transport/src/main/java/io/netty/channel/AbstractChannelHandlerContext.java +++ b/transport/src/main/java/io/netty/channel/AbstractChannelHandlerContext.java @@ -18,11 +18,13 @@ package io.netty.channel; import io.netty.buffer.ByteBufAllocator; import io.netty.util.Attribute; import io.netty.util.AttributeKey; -import io.netty.util.Recycler; import io.netty.util.ReferenceCountUtil; import io.netty.util.ResourceLeakHint; import io.netty.util.concurrent.EventExecutor; 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.ThrowableUtil; import io.netty.util.internal.ObjectUtil; @@ -1041,15 +1043,15 @@ abstract class AbstractChannelHandlerContext implements ChannelHandlerContext, R private static final int WRITE_TASK_OVERHEAD = SystemPropertyUtil.getInt("io.netty.transport.writeTaskSizeOverhead", 48); - private final Recycler.Handle handle; + private final Handle handle; private AbstractChannelHandlerContext ctx; private Object msg; private ChannelPromise promise; private int size; @SuppressWarnings("unchecked") - private AbstractWriteTask(Recycler.Handle handle) { - this.handle = (Recycler.Handle) handle; + private AbstractWriteTask(Handle handle) { + this.handle = (Handle) handle; } 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 { - private static final Recycler RECYCLER = new Recycler() { + private static final ObjectPool RECYCLER = ObjectPool.newPool(new ObjectCreator() { @Override - protected WriteTask newObject(Handle handle) { + public WriteTask newObject(Handle handle) { return new WriteTask(handle); } - }; + }); static WriteTask newInstance( AbstractChannelHandlerContext ctx, Object msg, ChannelPromise promise) { @@ -1119,19 +1121,20 @@ abstract class AbstractChannelHandlerContext implements ChannelHandlerContext, R return task; } - private WriteTask(Recycler.Handle handle) { + private WriteTask(Handle handle) { super(handle); } } static final class WriteAndFlushTask extends AbstractWriteTask { - private static final Recycler RECYCLER = new Recycler() { + private static final ObjectPool RECYCLER = ObjectPool.newPool( + new ObjectCreator() { @Override - protected WriteAndFlushTask newObject(Handle handle) { + public WriteAndFlushTask newObject(Handle handle) { return new WriteAndFlushTask(handle); } - }; + }); static WriteAndFlushTask newInstance( AbstractChannelHandlerContext ctx, Object msg, ChannelPromise promise) { @@ -1140,7 +1143,7 @@ abstract class AbstractChannelHandlerContext implements ChannelHandlerContext, R return task; } - private WriteAndFlushTask(Recycler.Handle handle) { + private WriteAndFlushTask(Handle handle) { super(handle); } diff --git a/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java b/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java index e042490f30..fca1c49e57 100644 --- a/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java +++ b/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java @@ -19,11 +19,12 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufHolder; import io.netty.buffer.Unpooled; 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.concurrent.FastThreadLocal; 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.SystemPropertyUtil; import io.netty.util.internal.logging.InternalLogger; @@ -798,12 +799,12 @@ public final class ChannelOutboundBuffer { } static final class Entry { - private static final Recycler RECYCLER = new Recycler() { + private static final ObjectPool RECYCLER = ObjectPool.newPool(new ObjectCreator() { @Override - protected Entry newObject(Handle handle) { + public Entry newObject(Handle handle) { return new Entry(handle); } - }; + }); private final Handle handle; Entry next; diff --git a/transport/src/main/java/io/netty/channel/PendingWriteQueue.java b/transport/src/main/java/io/netty/channel/PendingWriteQueue.java index 5d4624185a..efd552bd74 100644 --- a/transport/src/main/java/io/netty/channel/PendingWriteQueue.java +++ b/transport/src/main/java/io/netty/channel/PendingWriteQueue.java @@ -15,9 +15,10 @@ */ package io.netty.channel; -import io.netty.util.Recycler; import io.netty.util.ReferenceCountUtil; 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.logging.InternalLogger; 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. */ static final class PendingWrite { - private static final Recycler RECYCLER = new Recycler() { + private static final ObjectPool RECYCLER = ObjectPool.newPool(new ObjectCreator() { @Override - protected PendingWrite newObject(Handle handle) { + public PendingWrite newObject(ObjectPool.Handle handle) { return new PendingWrite(handle); } - }; + }); - private final Recycler.Handle handle; + private final ObjectPool.Handle handle; private PendingWrite next; private long size; private ChannelPromise promise; private Object msg; - private PendingWrite(Recycler.Handle handle) { + private PendingWrite(ObjectPool.Handle handle) { this.handle = handle; }