Manually GC direct ByteBuffer that is used by the Worker's on releaseExternalResources() to free up memory asap. See #638

This commit is contained in:
Norman Maurer 2012-10-04 09:02:53 +02:00
parent 6ca523a754
commit a6e89aa142
6 changed files with 39 additions and 3 deletions

View File

@ -49,10 +49,11 @@ import org.jboss.netty.channel.socket.Worker;
import org.jboss.netty.channel.socket.nio.SocketSendBufferPool.SendBuffer; import org.jboss.netty.channel.socket.nio.SocketSendBufferPool.SendBuffer;
import org.jboss.netty.logging.InternalLogger; import org.jboss.netty.logging.InternalLogger;
import org.jboss.netty.logging.InternalLoggerFactory; import org.jboss.netty.logging.InternalLoggerFactory;
import org.jboss.netty.util.ExternalResourceReleasable;
import org.jboss.netty.util.ThreadRenamingRunnable; import org.jboss.netty.util.ThreadRenamingRunnable;
import org.jboss.netty.util.internal.DeadLockProofWorker; import org.jboss.netty.util.internal.DeadLockProofWorker;
abstract class AbstractNioWorker implements Worker { abstract class AbstractNioWorker implements Worker, ExternalResourceReleasable {
private static final AtomicInteger nextId = new AtomicInteger(); private static final AtomicInteger nextId = new AtomicInteger();
@ -902,6 +903,11 @@ abstract class AbstractNioWorker implements Worker {
} }
} }
public void releaseExternalResources() {
sendBufferPool.releaseExternalResources();
}
/** /**
* Read is called when a Selector has been notified that the underlying channel * Read is called when a Selector has been notified that the underlying channel
* was something to be read. The channel would previously have registered its interest * was something to be read. The channel would previously have registered its interest

View File

@ -75,6 +75,9 @@ public abstract class AbstractNioWorkerPool<E extends AbstractNioWorker>
public void releaseExternalResources() { public void releaseExternalResources() {
ExecutorUtil.terminate(workerExecutor); ExecutorUtil.terminate(workerExecutor);
for (AbstractNioWorker worker: workers) {
worker.releaseExternalResources();
}
} }
} }

View File

@ -110,6 +110,12 @@ public class NioDatagramWorker extends AbstractNioWorker {
} }
@Override
public void releaseExternalResources() {
super.releaseExternalResources();
bufferAllocator.releaseExternalResources();
}
@Override @Override
protected boolean scheduleWriteIfNecessary(final AbstractNioChannel<?> channel) { protected boolean scheduleWriteIfNecessary(final AbstractNioChannel<?> channel) {
final Thread workerThread = thread; final Thread workerThread = thread;

View File

@ -130,6 +130,12 @@ public class NioWorker extends AbstractNioWorker {
return false; return false;
} }
@Override
public void releaseExternalResources() {
super.releaseExternalResources();
recvBufferPool.releaseExternalResources();
}
@Override @Override
protected Runnable createRegisterTask(AbstractNioChannel<?> channel, ChannelFuture future) { protected Runnable createRegisterTask(AbstractNioChannel<?> channel, ChannelFuture future) {
boolean server = !(channel instanceof NioClientSocketChannel); boolean server = !(channel instanceof NioClientSocketChannel);

View File

@ -17,9 +17,10 @@ package org.jboss.netty.channel.socket.nio;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.jboss.netty.util.ExternalResourceReleasable;
import org.jboss.netty.util.internal.ByteBufferUtil; import org.jboss.netty.util.internal.ByteBufferUtil;
final class SocketReceiveBufferAllocator { final class SocketReceiveBufferAllocator implements ExternalResourceReleasable {
private ByteBuffer buf; private ByteBuffer buf;
private int exceedCount; private int exceedCount;
@ -72,4 +73,10 @@ final class SocketReceiveBufferAllocator {
} }
return q << 10; return q << 10;
} }
public void releaseExternalResources() {
if (buf != null) {
ByteBufferUtil.destroy(buf);
}
}
} }

View File

@ -27,8 +27,10 @@ import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.CompositeChannelBuffer; import org.jboss.netty.buffer.CompositeChannelBuffer;
import org.jboss.netty.channel.DefaultFileRegion; import org.jboss.netty.channel.DefaultFileRegion;
import org.jboss.netty.channel.FileRegion; import org.jboss.netty.channel.FileRegion;
import org.jboss.netty.util.ExternalResourceReleasable;
import org.jboss.netty.util.internal.ByteBufferUtil;
final class SocketSendBufferPool { final class SocketSendBufferPool implements ExternalResourceReleasable {
private static final SendBuffer EMPTY_BUFFER = new EmptySendBuffer(); private static final SendBuffer EMPTY_BUFFER = new EmptySendBuffer();
@ -383,4 +385,10 @@ final class SocketSendBufferPool {
// Unpooled. // Unpooled.
} }
} }
public void releaseExternalResources() {
if (current.buffer != null) {
ByteBufferUtil.destroy(current.buffer);
}
}
} }