Use ResourceLeakDetectorFactory in HashedWheelTimer
Motivation: We recently added the ResourceLeakDetectorFactory but missed to updated HashedWheelTimer to use it. Modifications: - Add new abstract method to ResourceLeakDetectorFactory that allows to provide also samplingInterval and maxActive args. - Deprecate most constructors in ResourceLeakDetector and add doc explaining that people should use ResourceLeakDetectorFactory Result: Custom ResourceLeakDetectorFactory will also be used in HashedWheelTimer if configured.
This commit is contained in:
parent
bd0a74fca3
commit
57672d9854
@ -76,9 +76,8 @@ public class HashedWheelTimer implements Timer {
|
||||
static final InternalLogger logger =
|
||||
InternalLoggerFactory.getInstance(HashedWheelTimer.class);
|
||||
|
||||
private static final ResourceLeakDetector<HashedWheelTimer> leakDetector =
|
||||
new ResourceLeakDetector<HashedWheelTimer>(
|
||||
HashedWheelTimer.class, 1, Runtime.getRuntime().availableProcessors() * 4);
|
||||
private static final ResourceLeakDetector<HashedWheelTimer> leakDetector = ResourceLeakDetectorFactory.instance()
|
||||
.newResourceLeakDetector(HashedWheelTimer.class, 1, Runtime.getRuntime().availableProcessors() * 4L);
|
||||
|
||||
private static final AtomicIntegerFieldUpdater<HashedWheelTimer> WORKER_STATE_UPDATER;
|
||||
static {
|
||||
|
@ -109,7 +109,7 @@ public class ResourceLeakDetector<T> {
|
||||
}
|
||||
|
||||
// Should be power of two.
|
||||
private static final int DEFAULT_SAMPLING_INTERVAL = 128;
|
||||
static final int DEFAULT_SAMPLING_INTERVAL = 128;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #setLevel(Level)} instead.
|
||||
@ -159,18 +159,36 @@ public class ResourceLeakDetector<T> {
|
||||
|
||||
private long leakCheckCnt;
|
||||
|
||||
/**
|
||||
* @deprecated use {@link ResourceLeakDetectorFactory#newResourceLeakDetector(Class, int, long)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public ResourceLeakDetector(Class<?> resourceType) {
|
||||
this(simpleClassName(resourceType));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link ResourceLeakDetectorFactory#newResourceLeakDetector(Class, int, long)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public ResourceLeakDetector(String resourceType) {
|
||||
this(resourceType, DEFAULT_SAMPLING_INTERVAL, Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* This should not be used directly by users of {@link ResourceLeakDetector}.
|
||||
* Please use {@link ResourceLeakDetectorFactory#newResourceLeakDetector(Class)}
|
||||
* or {@link ResourceLeakDetectorFactory#newResourceLeakDetector(Class, int, long)}
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public ResourceLeakDetector(Class<?> resourceType, int samplingInterval, long maxActive) {
|
||||
this(simpleClassName(resourceType), samplingInterval, maxActive);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link ResourceLeakDetectorFactory#newResourceLeakDetector(Class, int, long)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public ResourceLeakDetector(String resourceType, int samplingInterval, long maxActive) {
|
||||
if (resourceType == null) {
|
||||
throw new NullPointerException("resourceType");
|
||||
@ -199,7 +217,7 @@ public class ResourceLeakDetector<T> {
|
||||
*
|
||||
* @return the {@link ResourceLeak} or {@code null}
|
||||
*/
|
||||
public ResourceLeak open(T obj) {
|
||||
public final ResourceLeak open(T obj) {
|
||||
Level level = ResourceLeakDetector.level;
|
||||
if (level == Level.DISABLED) {
|
||||
return null;
|
||||
|
@ -61,60 +61,82 @@ public abstract class ResourceLeakDetectorFactory {
|
||||
* @param <T> - the type of the resource class
|
||||
* @return - a new instance of {@link ResourceLeakDetector}
|
||||
*/
|
||||
public abstract <T> ResourceLeakDetector<T> newResourceLeakDetector(final Class<T> resource);
|
||||
public final <T> ResourceLeakDetector<T> newResourceLeakDetector(Class<T> resource) {
|
||||
return newResourceLeakDetector(resource, ResourceLeakDetector.DEFAULT_SAMPLING_INTERVAL, Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new instance of a {@link ResourceLeakDetector} with the given resource class.
|
||||
*
|
||||
* @param resource - the resource class used to initialize the {@link ResourceLeakDetector}
|
||||
* @param samplingInterval - the interval on which sampling takes place
|
||||
* @param maxActive - the maximum active instances
|
||||
* @param <T> - the type of the resource class
|
||||
* @return - a new instance of {@link ResourceLeakDetector}
|
||||
*/
|
||||
public abstract <T> ResourceLeakDetector<T> newResourceLeakDetector(
|
||||
Class<T> resource, int samplingInterval, long maxActive);
|
||||
|
||||
/**
|
||||
* Default implementation that loads custom leak detector via system property
|
||||
*/
|
||||
private static final class DefaultResourceLeakDetectorFactory extends ResourceLeakDetectorFactory {
|
||||
private final Constructor<?> customClassConstructor;
|
||||
|
||||
private final String customLeakDetector;
|
||||
private final Constructor customClassConstructor;
|
||||
|
||||
public DefaultResourceLeakDetectorFactory() {
|
||||
this.customLeakDetector = AccessController.doPrivileged(new PrivilegedAction<String>() {
|
||||
DefaultResourceLeakDetectorFactory() {
|
||||
String customLeakDetector;
|
||||
try {
|
||||
customLeakDetector = AccessController.doPrivileged(new PrivilegedAction<String>() {
|
||||
@Override
|
||||
public String run() {
|
||||
return SystemPropertyUtil.get("io.netty.customResourceLeakDetector");
|
||||
}
|
||||
});
|
||||
|
||||
this.customClassConstructor = customClassConstructor();
|
||||
} catch (Throwable cause) {
|
||||
logger.error("Could not access System property: io.netty.customResourceLeakDetector", cause);
|
||||
customLeakDetector = null;
|
||||
}
|
||||
customClassConstructor = customLeakDetector == null ? null : customClassConstructor(customLeakDetector);
|
||||
}
|
||||
|
||||
private Constructor customClassConstructor() {
|
||||
private static Constructor<?> customClassConstructor(String customLeakDetector) {
|
||||
try {
|
||||
if (customLeakDetector != null) {
|
||||
final Class<?> detectorClass = Class.forName(customLeakDetector, true,
|
||||
PlatformDependent.getSystemClassLoader());
|
||||
|
||||
if (ResourceLeakDetector.class.isAssignableFrom(detectorClass)) {
|
||||
return detectorClass.getConstructor(Class.class);
|
||||
return detectorClass.getConstructor(Class.class, int.class, long.class);
|
||||
} else {
|
||||
logger.error("Class {} does not inherit from ResourceLeakDetector.", customLeakDetector);
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
logger.error("Could not load custom resource leak detector class provided: " + customLeakDetector, t);
|
||||
logger.error("Could not load custom resource leak detector class provided: {}",
|
||||
customLeakDetector, t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ResourceLeakDetector<T> newResourceLeakDetector(final Class<T> resource) {
|
||||
try {
|
||||
public <T> ResourceLeakDetector<T> newResourceLeakDetector(
|
||||
Class<T> resource, int samplingInterval, long maxActive) {
|
||||
if (customClassConstructor != null) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
ResourceLeakDetector<T> leakDetector =
|
||||
(ResourceLeakDetector<T>) customClassConstructor.newInstance(resource);
|
||||
logger.debug("Loaded custom ResourceLeakDetector: {}", customLeakDetector);
|
||||
(ResourceLeakDetector<T>) customClassConstructor.newInstance(
|
||||
resource, samplingInterval, maxActive);
|
||||
logger.debug("Loaded custom ResourceLeakDetector: {}",
|
||||
customClassConstructor.getDeclaringClass().getName());
|
||||
return leakDetector;
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
logger.error("Could not load custom resource leak detector provided: {} with the given resource: {}",
|
||||
customLeakDetector, resource, t);
|
||||
logger.error(
|
||||
"Could not load custom resource leak detector provided: {} with the given resource: {}",
|
||||
customClassConstructor.getDeclaringClass().getName(), resource, t);
|
||||
}
|
||||
}
|
||||
|
||||
ResourceLeakDetector<T> resourceLeakDetector = new ResourceLeakDetector<T>(resource);
|
||||
ResourceLeakDetector<T> resourceLeakDetector = new ResourceLeakDetector<T>(
|
||||
resource, samplingInterval, maxActive);
|
||||
logger.debug("Loaded default ResourceLeakDetector: {}", resourceLeakDetector);
|
||||
return resourceLeakDetector;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user