Remove allocation from ResourceLeakDetector

Motivation:
RLD allocates an ArrayDeque in anticipation of recording access
points.  If the leak detection level is less than ADVANCED though,
the dequeue is never used.  Since SIMPLE is the default level,
there is a minor perf win to not preemptively allocate it.

This showed up in garbage profiling when creation a high number of
buffers.

Modifications:
Only allocate the dequeue if it will be used.

Result:
Less garbage created.
This commit is contained in:
Carl Mastrangelo 2017-09-14 19:08:23 -07:00 committed by Norman Maurer
parent b1332bf12e
commit b32cd26a96

View File

@ -27,6 +27,7 @@ import java.util.ArrayDeque;
import java.util.Deque;
import java.util.concurrent.ConcurrentMap;
import static io.netty.util.internal.EmptyArrays.EMPTY_OBJECTS;
import static io.netty.util.internal.StringUtil.EMPTY_STRING;
import static io.netty.util.internal.StringUtil.NEWLINE;
import static io.netty.util.internal.StringUtil.simpleClassName;
@ -116,7 +117,6 @@ public class ResourceLeakDetector<T> {
}
}
// Should be power of two.
static final int DEFAULT_SAMPLING_INTERVAL = 128;
/**
@ -329,7 +329,7 @@ public class ResourceLeakDetector<T> {
private final class DefaultResourceLeak extends PhantomReference<Object> implements ResourceLeakTracker<T>,
ResourceLeak {
private final String creationRecord;
private final Deque<String> lastRecords = new ArrayDeque<String>();
private final Deque<String> lastRecords;
private final int trackedHash;
private int removedRecords;
@ -347,8 +347,10 @@ public class ResourceLeakDetector<T> {
Level level = getLevel();
if (level.ordinal() >= Level.ADVANCED.ordinal()) {
creationRecord = newRecord(null, 3);
lastRecords = new ArrayDeque<String>();
} else {
creationRecord = null;
lastRecords = null;
}
allLeaks.put(this, LeakEntry.INSTANCE);
}
@ -407,9 +409,14 @@ public class ResourceLeakDetector<T> {
final Object[] array;
final int removedRecords;
synchronized (lastRecords) {
array = lastRecords.toArray();
removedRecords = this.removedRecords;
if (lastRecords != null) {
synchronized (lastRecords) {
array = lastRecords.toArray();
removedRecords = this.removedRecords;
}
} else {
removedRecords = 0;
array = EMPTY_OBJECTS;
}
StringBuilder buf = new StringBuilder(16384).append(NEWLINE);