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
This commit is contained in:
parent
3b114a51df
commit
0d549706f1
@ -19,10 +19,13 @@ import ch.qos.logback.classic.Logger;
|
|||||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||||
import ch.qos.logback.core.Appender;
|
import ch.qos.logback.core.Appender;
|
||||||
import io.netty.channel.local.LocalChannel;
|
import io.netty.channel.local.LocalChannel;
|
||||||
|
import io.netty.util.concurrent.DefaultExecutorFactory;
|
||||||
import io.netty.util.concurrent.EventExecutor;
|
import io.netty.util.concurrent.EventExecutor;
|
||||||
import io.netty.util.concurrent.PausableEventExecutor;
|
import io.netty.util.concurrent.PausableEventExecutor;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -32,7 +35,7 @@ import java.util.List;
|
|||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
@ -52,9 +55,16 @@ public class SingleThreadEventLoopTest {
|
|||||||
public void run() { }
|
public void run() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static Executor executor;
|
||||||
|
|
||||||
private SingleThreadEventLoopA loopA;
|
private SingleThreadEventLoopA loopA;
|
||||||
private SingleThreadEventLoopB loopB;
|
private SingleThreadEventLoopB loopB;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void newExecutor() {
|
||||||
|
executor = new DefaultExecutorFactory("SingleThreadEventLoopTest").newExecutor(2);
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void newEventLoop() {
|
public void newEventLoop() {
|
||||||
loopA = new SingleThreadEventLoopA();
|
loopA = new SingleThreadEventLoopA();
|
||||||
@ -689,7 +699,7 @@ public class SingleThreadEventLoopTest {
|
|||||||
final AtomicInteger cleanedUp = new AtomicInteger();
|
final AtomicInteger cleanedUp = new AtomicInteger();
|
||||||
|
|
||||||
SingleThreadEventLoopA() {
|
SingleThreadEventLoopA() {
|
||||||
super(null, Executors.newSingleThreadExecutor(), true);
|
super(null, executor, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -719,7 +729,7 @@ public class SingleThreadEventLoopTest {
|
|||||||
private volatile boolean interrupted;
|
private volatile boolean interrupted;
|
||||||
|
|
||||||
SingleThreadEventLoopB() {
|
SingleThreadEventLoopB() {
|
||||||
super(null, Executors.newSingleThreadExecutor(), false);
|
super(null, executor, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user