From 5d4e34b021229b988d41742e0c85dba0d940260e Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Fri, 29 May 2015 08:04:34 +0200 Subject: [PATCH] [#3837] Null out ByteBuffer[] array once done Motivation: the ByteBuffer[] that we keep in the ThreadLocal are never nulled out which can lead to have ByteBuffer instances sit there forever. This is even a bigger problem if nioBuffer() of ByteBuffer returns a new ByteBuffer that can not be destroyed by ByteBuffer.release(). Modifications: Null out ByteBuffer array after processing. Result: No more dangling references after done. --- .../io/netty/channel/ChannelOutboundBuffer.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java b/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java index a8e1d7b404..09cf507e90 100644 --- a/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java +++ b/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java @@ -30,6 +30,7 @@ import io.netty.util.internal.logging.InternalLoggerFactory; import java.nio.ByteBuffer; import java.nio.channels.ClosedChannelException; +import java.util.Arrays; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import java.util.concurrent.atomic.AtomicLongFieldUpdater; @@ -245,6 +246,7 @@ public final class ChannelOutboundBuffer { public boolean remove() { Entry e = flushedEntry; if (e == null) { + clearNioBuffers(); return false; } Object msg = e.msg; @@ -279,6 +281,7 @@ public final class ChannelOutboundBuffer { private boolean remove0(Throwable cause, boolean notifyWritability) { Entry e = flushedEntry; if (e == null) { + clearNioBuffers(); return false; } Object msg = e.msg; @@ -345,6 +348,17 @@ public final class ChannelOutboundBuffer { break; } } + clearNioBuffers(); + } + + // Clear all ByteBuffer from the array so these can be GC'ed. + // See https://github.com/netty/netty/issues/3837 + private void clearNioBuffers() { + int count = nioBufferCount; + if (count > 0) { + nioBufferCount = 0; + Arrays.fill(NIO_BUFFERS.get(), 0, count, null); + } } /** @@ -651,6 +665,7 @@ public final class ChannelOutboundBuffer { } finally { inFail = false; } + clearNioBuffers(); } private static void safeSuccess(ChannelPromise promise) {