From 6732c6761bcc06183a71ad676b0110d2d226ab68 Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Mon, 10 Jun 2013 19:52:56 +0900 Subject: [PATCH] Recycle PooledByteBuf partially - Related issue: #1397 - Resource leak detection should be turned off and the maxCapacity has to be Integer.MAX_VALUE - It's technically possible to pool PooledByteBufs with different maxCapacity, which will be addressed in another commit. --- .../main/java/io/netty/buffer/PoolArena.java | 6 ++--- .../java/io/netty/buffer/PooledByteBuf.java | 23 ++++++++++++++-- .../io/netty/buffer/PooledDirectByteBuf.java | 26 +++++++++++++++++-- .../io/netty/buffer/PooledHeapByteBuf.java | 25 ++++++++++++++++-- .../buffer/PooledUnsafeDirectByteBuf.java | 26 +++++++++++++++++-- 5 files changed, 95 insertions(+), 11 deletions(-) diff --git a/buffer/src/main/java/io/netty/buffer/PoolArena.java b/buffer/src/main/java/io/netty/buffer/PoolArena.java index a5d3129195..57c4385e92 100644 --- a/buffer/src/main/java/io/netty/buffer/PoolArena.java +++ b/buffer/src/main/java/io/netty/buffer/PoolArena.java @@ -345,7 +345,7 @@ abstract class PoolArena { @Override protected PooledByteBuf newByteBuf(int maxCapacity) { - return new PooledHeapByteBuf(maxCapacity); + return PooledHeapByteBuf.newInstance(maxCapacity); } @Override @@ -385,9 +385,9 @@ abstract class PoolArena { @Override protected PooledByteBuf newByteBuf(int maxCapacity) { if (HAS_UNSAFE) { - return new PooledUnsafeDirectByteBuf(maxCapacity); + return PooledUnsafeDirectByteBuf.newInstance(maxCapacity); } else { - return new PooledDirectByteBuf(maxCapacity); + return PooledDirectByteBuf.newInstance(maxCapacity); } } diff --git a/buffer/src/main/java/io/netty/buffer/PooledByteBuf.java b/buffer/src/main/java/io/netty/buffer/PooledByteBuf.java index 153c3475c9..18f7ef3d32 100644 --- a/buffer/src/main/java/io/netty/buffer/PooledByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/PooledByteBuf.java @@ -16,7 +16,9 @@ package io.netty.buffer; +import io.netty.util.Recycler; import io.netty.util.ResourceLeak; +import io.netty.util.ResourceLeakDetector; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -24,6 +26,7 @@ import java.nio.ByteOrder; abstract class PooledByteBuf extends AbstractReferenceCountedByteBuf { private final ResourceLeak leak; + private final Recycler.Handle recyclerHandle; protected PoolChunk chunk; protected long handle; @@ -34,9 +37,10 @@ abstract class PooledByteBuf extends AbstractReferenceCountedByteBuf { private ByteBuffer tmpNioBuf; - protected PooledByteBuf(int maxCapacity) { + protected PooledByteBuf(Recycler.Handle recyclerHandle, int maxCapacity) { super(maxCapacity); leak = leakDetector.open(this); + this.recyclerHandle = recyclerHandle; } void init(PoolChunk chunk, long handle, int offset, int length, int maxLength) { @@ -141,10 +145,25 @@ abstract class PooledByteBuf extends AbstractReferenceCountedByteBuf { this.handle = -1; memory = null; chunk.arena.free(chunk, handle); - leak.close(); + if (ResourceLeakDetector.ENABLED) { + leak.close(); + } else { + recycle(); + } } } + @SuppressWarnings("unchecked") + private void recycle() { + Recycler.Handle recyclerHandle = this.recyclerHandle; + if (recyclerHandle != null) { + setRefCnt(1); + ((Recycler) recycler()).recycle(this, recyclerHandle); + } + } + + protected abstract Recycler recycler(); + protected final int idx(int index) { return offset + index; } diff --git a/buffer/src/main/java/io/netty/buffer/PooledDirectByteBuf.java b/buffer/src/main/java/io/netty/buffer/PooledDirectByteBuf.java index 588b593535..10ac98c9f0 100644 --- a/buffer/src/main/java/io/netty/buffer/PooledDirectByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/PooledDirectByteBuf.java @@ -16,6 +16,8 @@ package io.netty.buffer; +import io.netty.util.Recycler; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -26,8 +28,23 @@ import java.nio.channels.ScatteringByteChannel; final class PooledDirectByteBuf extends PooledByteBuf { - PooledDirectByteBuf(int maxCapacity) { - super(maxCapacity); + private static final Recycler RECYCLER = new Recycler() { + @Override + protected PooledDirectByteBuf newObject(Handle handle) { + return new PooledDirectByteBuf(handle, Integer.MAX_VALUE); + } + }; + + static PooledDirectByteBuf newInstance(int maxCapacity) { + if (maxCapacity == Integer.MAX_VALUE) { + return RECYCLER.get(); + } else { + return new PooledDirectByteBuf(null, maxCapacity); + } + } + + private PooledDirectByteBuf(Recycler.Handle recyclerHandle, int maxCapacity) { + super(recyclerHandle, maxCapacity); } @Override @@ -277,4 +294,9 @@ final class PooledDirectByteBuf extends PooledByteBuf { public long memoryAddress() { throw new UnsupportedOperationException(); } + + @Override + protected Recycler recycler() { + return RECYCLER; + } } diff --git a/buffer/src/main/java/io/netty/buffer/PooledHeapByteBuf.java b/buffer/src/main/java/io/netty/buffer/PooledHeapByteBuf.java index 6f2432786a..5e2de4d4d8 100644 --- a/buffer/src/main/java/io/netty/buffer/PooledHeapByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/PooledHeapByteBuf.java @@ -14,6 +14,7 @@ package io.netty.buffer; +import io.netty.util.Recycler; import io.netty.util.internal.PlatformDependent; import java.io.IOException; @@ -26,8 +27,23 @@ import java.nio.channels.ScatteringByteChannel; final class PooledHeapByteBuf extends PooledByteBuf { - PooledHeapByteBuf(int maxCapacity) { - super(maxCapacity); + private static final Recycler RECYCLER = new Recycler() { + @Override + protected PooledHeapByteBuf newObject(Handle handle) { + return new PooledHeapByteBuf(handle, Integer.MAX_VALUE); + } + }; + + static PooledHeapByteBuf newInstance(int maxCapacity) { + if (maxCapacity == Integer.MAX_VALUE) { + return RECYCLER.get(); + } else { + return new PooledHeapByteBuf(null, maxCapacity); + } + } + + private PooledHeapByteBuf(Recycler.Handle recyclerHandle, int maxCapacity) { + super(recyclerHandle, maxCapacity); } @Override @@ -258,4 +274,9 @@ final class PooledHeapByteBuf extends PooledByteBuf { protected ByteBuffer newInternalNioBuffer(byte[] memory) { return ByteBuffer.wrap(memory); } + + @Override + protected Recycler recycler() { + return RECYCLER; + } } diff --git a/buffer/src/main/java/io/netty/buffer/PooledUnsafeDirectByteBuf.java b/buffer/src/main/java/io/netty/buffer/PooledUnsafeDirectByteBuf.java index b1240472bb..561539d374 100644 --- a/buffer/src/main/java/io/netty/buffer/PooledUnsafeDirectByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/PooledUnsafeDirectByteBuf.java @@ -16,6 +16,7 @@ package io.netty.buffer; +import io.netty.util.Recycler; import io.netty.util.internal.PlatformDependent; import java.io.IOException; @@ -30,10 +31,26 @@ import java.nio.channels.ScatteringByteChannel; final class PooledUnsafeDirectByteBuf extends PooledByteBuf { private static final boolean NATIVE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; + + private static final Recycler RECYCLER = new Recycler() { + @Override + protected PooledUnsafeDirectByteBuf newObject(Handle handle) { + return new PooledUnsafeDirectByteBuf(handle, Integer.MAX_VALUE); + } + }; + + static PooledUnsafeDirectByteBuf newInstance(int maxCapacity) { + if (maxCapacity == Integer.MAX_VALUE) { + return RECYCLER.get(); + } else { + return new PooledUnsafeDirectByteBuf(null, maxCapacity); + } + } + private long memoryAddress; - PooledUnsafeDirectByteBuf(int maxCapacity) { - super(maxCapacity); + private PooledUnsafeDirectByteBuf(Recycler.Handle recyclerHandle, int maxCapacity) { + super(recyclerHandle, maxCapacity); } @Override @@ -318,4 +335,9 @@ final class PooledUnsafeDirectByteBuf extends PooledByteBuf { private long addr(int index) { return memoryAddress + index; } + + @Override + protected Recycler recycler() { + return RECYCLER; + } }