From 0d549706f1cd0609a86fcfc96086de59d2c6191c Mon Sep 17 00:00:00 2001 From: Jakob Buchgraber Date: Fri, 29 Aug 2014 17:00:55 +0200 Subject: [PATCH] Reduce Memory Usage of SingleThreadEventLoopTest Motivation: The SingleThreadEventLoopTest allocated up to half a gigabyte of memory per run, causing up to 50 GC runs in ~20 seconds. Modification: Charlie Hunt identified TLAB allocations to be the root cause of this excessive memory usage [1]. By reusing the Executor in every test we can reduce the memory usage by >50%. Result: Lower Memory Usage and fewer Garbage Collector runs. Helps to resolve GitHub issue #2841. [1] https://twitter.com/charlesjhunt/status/505351389317722112 --- .../netty/channel/SingleThreadEventLoopTest.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/transport/src/test/java/io/netty/channel/SingleThreadEventLoopTest.java b/transport/src/test/java/io/netty/channel/SingleThreadEventLoopTest.java index 29deace9bb..dc8621b8c3 100644 --- a/transport/src/test/java/io/netty/channel/SingleThreadEventLoopTest.java +++ b/transport/src/test/java/io/netty/channel/SingleThreadEventLoopTest.java @@ -19,10 +19,13 @@ import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.Appender; import io.netty.channel.local.LocalChannel; +import io.netty.util.concurrent.DefaultExecutorFactory; import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.PausableEventExecutor; import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.slf4j.LoggerFactory; @@ -32,7 +35,7 @@ import java.util.List; import java.util.Queue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executors; +import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ScheduledFuture; @@ -52,9 +55,16 @@ public class SingleThreadEventLoopTest { public void run() { } }; + private static Executor executor; + private SingleThreadEventLoopA loopA; private SingleThreadEventLoopB loopB; + @BeforeClass + public static void newExecutor() { + executor = new DefaultExecutorFactory("SingleThreadEventLoopTest").newExecutor(2); + } + @Before public void newEventLoop() { loopA = new SingleThreadEventLoopA(); @@ -689,7 +699,7 @@ public class SingleThreadEventLoopTest { final AtomicInteger cleanedUp = new AtomicInteger(); SingleThreadEventLoopA() { - super(null, Executors.newSingleThreadExecutor(), true); + super(null, executor, true); } @Override @@ -719,7 +729,7 @@ public class SingleThreadEventLoopTest { private volatile boolean interrupted; SingleThreadEventLoopB() { - super(null, Executors.newSingleThreadExecutor(), false); + super(null, executor, false); } @Override