From fd0ae840b64120efd2a29ba96f0467fda0f21dad Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Thu, 1 Dec 2016 08:13:33 +0100 Subject: [PATCH] Small performance improvements in ResourceLeakDetector Motivation: 42fba015ce82ab4ab30e547c888db82fe74094e9 changed the implemention of ResourceLeakDetector to improve performance. While this was done a branch was missed that can be removed. Beside this using a Boolean as value for the ConcurrentMap is sub-optimal as when calling remove(key, value) an uncessary instanceof check and cast is needed on each removal. Modifications: - Remove branch which is not needed anymore - Replace usage of Boolean as value type of the ConcurrentMap and use our own special type which only compute hash-code one time and use a == operation for equals(...) to reduce overhead present when using Boolean. Result: Faster and cleaner ResourceLeakDetector. --- .../io/netty/util/ResourceLeakDetector.java | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/common/src/main/java/io/netty/util/ResourceLeakDetector.java b/common/src/main/java/io/netty/util/ResourceLeakDetector.java index 6e37561796..a4cd566553 100644 --- a/common/src/main/java/io/netty/util/ResourceLeakDetector.java +++ b/common/src/main/java/io/netty/util/ResourceLeakDetector.java @@ -144,7 +144,7 @@ public class ResourceLeakDetector { } /** the collection of active resources */ - private final ConcurrentMap allLeaks = PlatformDependent.newConcurrentHashMap(); + private final ConcurrentMap allLeaks = PlatformDependent.newConcurrentHashMap(); private final ReferenceQueue refQueue = new ReferenceQueue(); private final ConcurrentMap reportedLeaks = PlatformDependent.newConcurrentHashMap(); @@ -306,20 +306,18 @@ public class ResourceLeakDetector { private int removedRecords; DefaultResourceLeak(Object referent) { - super(referent, referent != null? refQueue : null); + super(referent, refQueue); - if (referent != null) { - Level level = getLevel(); - if (level.ordinal() >= Level.ADVANCED.ordinal()) { - creationRecord = newRecord(null, 3); - } else { - creationRecord = null; - } + assert referent != null; - allLeaks.put(this, Boolean.TRUE); + Level level = getLevel(); + if (level.ordinal() >= Level.ADVANCED.ordinal()) { + creationRecord = newRecord(null, 3); } else { creationRecord = null; } + + allLeaks.put(this, LeakEntry.INSTANCE); } @Override @@ -352,7 +350,7 @@ public class ResourceLeakDetector { @Override public boolean close() { // Use the ConcurrentMap remove method, which avoids allocating an iterator. - return allLeaks.remove(this, Boolean.TRUE); + return allLeaks.remove(this, LeakEntry.INSTANCE); } @Override @@ -451,4 +449,21 @@ public class ResourceLeakDetector { return buf.toString(); } + + private static final class LeakEntry { + static final LeakEntry INSTANCE = new LeakEntry(); + private static final int HASH = System.identityHashCode(INSTANCE); + + private LeakEntry() { } + + @Override + public int hashCode() { + return HASH; + } + + @Override + public boolean equals(Object obj) { + return obj == this; + } + } }