Remove deprecated stuff around ResourceLeakDetector (#11572)
Motivation: A number of classes and APIs around the ResourceLeakDetector have been deprecated for removal in Netty 5.x, because better alternatives exist. Modification: Remove everything in and around ResourceLeakDetector that is deprecated, and fix the few usages that were found. Result: Less deprecated code.
This commit is contained in:
parent
11fcfe1f73
commit
a3d5617d45
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you under the Apache License,
|
||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package io.netty.util;
|
||||
|
||||
/**
|
||||
* @deprecated please use {@link ResourceLeakTracker} as it may lead to false-positives.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface ResourceLeak {
|
||||
/**
|
||||
* Records the caller's current stack trace so that the {@link ResourceLeakDetector} can tell where the leaked
|
||||
* resource was accessed lastly. This method is a shortcut to {@link #record(Object) record(null)}.
|
||||
*/
|
||||
void record();
|
||||
|
||||
/**
|
||||
* Records the caller's current stack trace and the specified additional arbitrary information
|
||||
* so that the {@link ResourceLeakDetector} can tell where the leaked resource was accessed lastly.
|
||||
*/
|
||||
void record(Object hint);
|
||||
|
||||
/**
|
||||
* Close the leak so that {@link ResourceLeakDetector} does not warn about leaked resources.
|
||||
*
|
||||
* @return {@code true} if called first time, {@code false} if called already
|
||||
*/
|
||||
boolean close();
|
||||
}
|
@ -114,14 +114,6 @@ public class ResourceLeakDetector<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #setLevel(Level)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static void setEnabled(boolean enabled) {
|
||||
setLevel(enabled? Level.SIMPLE : Level.DISABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if resource leak detection is enabled.
|
||||
*/
|
||||
@ -154,70 +146,15 @@ public class ResourceLeakDetector<T> {
|
||||
private final int samplingInterval;
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link ResourceLeakDetector#ResourceLeakDetector(Class, int)}.
|
||||
* <p>
|
||||
* This should not be used directly by users of {@link ResourceLeakDetector}.
|
||||
* Please use {@link ResourceLeakDetectorFactory#newResourceLeakDetector(Class)}
|
||||
* or {@link ResourceLeakDetectorFactory#newResourceLeakDetector(Class, int, long)}
|
||||
*
|
||||
* @param maxActive This is deprecated and will be ignored.
|
||||
* or {@link ResourceLeakDetectorFactory#newResourceLeakDetector(Class, int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public ResourceLeakDetector(Class<?> resourceType, int samplingInterval, long maxActive) {
|
||||
this(resourceType, samplingInterval);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
this(simpleClassName(resourceType), samplingInterval, Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link ResourceLeakDetectorFactory#newResourceLeakDetector(Class, int, long)}.
|
||||
* <p>
|
||||
* @param maxActive This is deprecated and will be ignored.
|
||||
*/
|
||||
@Deprecated
|
||||
public ResourceLeakDetector(String resourceType, int samplingInterval, long maxActive) {
|
||||
requireNonNull(resourceType, "resourceType");
|
||||
|
||||
this.resourceType = resourceType;
|
||||
this.resourceType = simpleClassName(resourceType);
|
||||
this.samplingInterval = samplingInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ResourceLeak} which is expected to be closed via {@link ResourceLeak#close()} when the
|
||||
* related resource is deallocated.
|
||||
*
|
||||
* @return the {@link ResourceLeak} or {@code null}
|
||||
* @deprecated use {@link #track(Object)}
|
||||
*/
|
||||
@Deprecated
|
||||
public final ResourceLeak open(T obj) {
|
||||
return track0(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ResourceLeakTracker} which is expected to be closed via
|
||||
* {@link ResourceLeakTracker#close(Object)} when the related resource is deallocated.
|
||||
@ -326,9 +263,8 @@ public class ResourceLeakDetector<T> {
|
||||
protected void reportInstancesLeak(String resourceType) {
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static final class DefaultResourceLeak<T>
|
||||
extends WeakReference<Object> implements ResourceLeakTracker<T>, ResourceLeak {
|
||||
extends WeakReference<Object> implements ResourceLeakTracker<T> {
|
||||
|
||||
@SuppressWarnings("unchecked") // generics and updaters do not mix.
|
||||
private static final AtomicReferenceFieldUpdater<DefaultResourceLeak<?>, TraceRecord> headUpdater =
|
||||
@ -437,24 +373,19 @@ public class ResourceLeakDetector<T> {
|
||||
return allLeaks.remove(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean close() {
|
||||
if (allLeaks.remove(this)) {
|
||||
// Call clear so the reference is not even enqueued.
|
||||
clear();
|
||||
headUpdater.set(this, null);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean close(T trackedObject) {
|
||||
// Ensure that the object that was tracked is the same as the one that was passed to close(...).
|
||||
assert trackedHash == System.identityHashCode(trackedObject);
|
||||
|
||||
try {
|
||||
return close();
|
||||
if (allLeaks.remove(this)) {
|
||||
// Call clear so the reference is not even enqueued.
|
||||
clear();
|
||||
headUpdater.set(this, null);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} finally {
|
||||
// Ensure the tracked object remain live and strongly referenced, until close() has finished.
|
||||
Reference.reachabilityFence(trackedObject);
|
||||
@ -518,7 +449,7 @@ public class ResourceLeakDetector<T> {
|
||||
private static final AtomicReference<String[]> excludedMethods =
|
||||
new AtomicReference<>(EmptyArrays.EMPTY_STRINGS);
|
||||
|
||||
public static void addExclusions(Class clz, String ... methodNames) {
|
||||
public static void addExclusions(Class<?> clz, String ... methodNames) {
|
||||
Set<String> nameSet = new HashSet<>(Arrays.asList(methodNames));
|
||||
// Use loop rather than lookup. This avoids knowing the parameters, and doesn't have to handle
|
||||
// NoSuchMethodException.
|
||||
|
@ -66,39 +66,20 @@ public abstract class ResourceLeakDetectorFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #newResourceLeakDetector(Class, int)} instead.
|
||||
* <p>
|
||||
* 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 This is deprecated and will be ignored.
|
||||
* @param <T> the type of the resource class
|
||||
* @return a new instance of {@link ResourceLeakDetector}
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract <T> ResourceLeakDetector<T> newResourceLeakDetector(
|
||||
Class<T> resource, int samplingInterval, long maxActive);
|
||||
|
||||
/**
|
||||
* 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 <T> the type of the resource class
|
||||
* @return a new instance of {@link ResourceLeakDetector}
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public <T> ResourceLeakDetector<T> newResourceLeakDetector(Class<T> resource, int samplingInterval) {
|
||||
ObjectUtil.checkPositive(samplingInterval, "samplingInterval");
|
||||
return newResourceLeakDetector(resource, samplingInterval, Long.MAX_VALUE);
|
||||
}
|
||||
Class<T> resource, int samplingInterval);
|
||||
|
||||
/**
|
||||
* Default implementation that loads custom leak detector via system property
|
||||
*/
|
||||
private static final class DefaultResourceLeakDetectorFactory extends ResourceLeakDetectorFactory {
|
||||
private final Constructor<?> obsoleteCustomClassConstructor;
|
||||
private final Constructor<?> customClassConstructor;
|
||||
|
||||
DefaultResourceLeakDetectorFactory() {
|
||||
@ -110,30 +91,12 @@ public abstract class ResourceLeakDetectorFactory {
|
||||
customLeakDetector = null;
|
||||
}
|
||||
if (customLeakDetector == null) {
|
||||
obsoleteCustomClassConstructor = customClassConstructor = null;
|
||||
customClassConstructor = null;
|
||||
} else {
|
||||
obsoleteCustomClassConstructor = obsoleteCustomClassConstructor(customLeakDetector);
|
||||
customClassConstructor = customClassConstructor(customLeakDetector);
|
||||
}
|
||||
}
|
||||
|
||||
private static Constructor<?> obsoleteCustomClassConstructor(String customLeakDetector) {
|
||||
try {
|
||||
final Class<?> detectorClass = Class.forName(customLeakDetector, true,
|
||||
PlatformDependent.getSystemClassLoader());
|
||||
|
||||
if (ResourceLeakDetector.class.isAssignableFrom(detectorClass)) {
|
||||
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);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Constructor<?> customClassConstructor(String customLeakDetector) {
|
||||
try {
|
||||
final Class<?> detectorClass = Class.forName(customLeakDetector, true,
|
||||
@ -151,34 +114,9 @@ public abstract class ResourceLeakDetectorFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public <T> ResourceLeakDetector<T> newResourceLeakDetector(Class<T> resource, int samplingInterval,
|
||||
long maxActive) {
|
||||
if (obsoleteCustomClassConstructor != null) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
ResourceLeakDetector<T> leakDetector =
|
||||
(ResourceLeakDetector<T>) obsoleteCustomClassConstructor.newInstance(
|
||||
resource, samplingInterval, maxActive);
|
||||
logger.debug("Loaded custom ResourceLeakDetector: {}",
|
||||
obsoleteCustomClassConstructor.getDeclaringClass().getName());
|
||||
return leakDetector;
|
||||
} catch (Throwable t) {
|
||||
logger.error(
|
||||
"Could not load custom resource leak detector provided: {} with the given resource: {}",
|
||||
obsoleteCustomClassConstructor.getDeclaringClass().getName(), resource, t);
|
||||
}
|
||||
}
|
||||
|
||||
ResourceLeakDetector<T> resourceLeakDetector = new ResourceLeakDetector<>(resource, samplingInterval,
|
||||
maxActive);
|
||||
logger.debug("Loaded default ResourceLeakDetector: {}", resourceLeakDetector);
|
||||
return resourceLeakDetector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ResourceLeakDetector<T> newResourceLeakDetector(Class<T> resource, int samplingInterval) {
|
||||
ObjectUtil.checkPositive(samplingInterval, "samplingInterval");
|
||||
if (customClassConstructor != null) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you under the Apache License,
|
||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package io.netty.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @deprecated This class will be removed in the future version.
|
||||
*/
|
||||
@Deprecated
|
||||
public class ResourceLeakException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 7186453858343358280L;
|
||||
|
||||
private final StackTraceElement[] cachedStackTrace;
|
||||
|
||||
public ResourceLeakException() {
|
||||
cachedStackTrace = getStackTrace();
|
||||
}
|
||||
|
||||
public ResourceLeakException(String message) {
|
||||
super(message);
|
||||
cachedStackTrace = getStackTrace();
|
||||
}
|
||||
|
||||
public ResourceLeakException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
cachedStackTrace = getStackTrace();
|
||||
}
|
||||
|
||||
public ResourceLeakException(Throwable cause) {
|
||||
super(cause);
|
||||
cachedStackTrace = getStackTrace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hashCode = 0;
|
||||
for (StackTraceElement e: cachedStackTrace) {
|
||||
hashCode = hashCode * 31 + e.hashCode();
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof ResourceLeakException)) {
|
||||
return false;
|
||||
}
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return Arrays.equals(cachedStackTrace, ((ResourceLeakException) o).cachedStackTrace);
|
||||
}
|
||||
}
|
@ -76,8 +76,8 @@ public class ResourceLeakDetectorTest {
|
||||
}
|
||||
boolean closed = r.close();
|
||||
if (checkClosed && !closed) {
|
||||
error.compareAndSet(null,
|
||||
new AssertionError("ResourceLeak.close() returned 'false' but expected 'true'"));
|
||||
error.compareAndSet(null, new AssertionError(
|
||||
"ResourceLeakTracker.close() returned 'false' but expected 'true'"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -121,8 +121,7 @@ public class ResourceLeakDetectorTest {
|
||||
|
||||
private static final class DefaultResource implements Resource {
|
||||
// Sample every allocation
|
||||
static final TestResourceLeakDetector<Resource> detector = new TestResourceLeakDetector<>(
|
||||
Resource.class, 1, Integer.MAX_VALUE);
|
||||
static final TestResourceLeakDetector<Resource> detector = new TestResourceLeakDetector<>(Resource.class, 1);
|
||||
|
||||
@Override
|
||||
public boolean close() {
|
||||
@ -145,8 +144,8 @@ public class ResourceLeakDetectorTest {
|
||||
|
||||
private final AtomicReference<Throwable> error = new AtomicReference<>();
|
||||
|
||||
TestResourceLeakDetector(Class<?> resourceType, int samplingInterval, long maxActive) {
|
||||
super(resourceType, samplingInterval, maxActive);
|
||||
TestResourceLeakDetector(Class<?> resourceType, int samplingInterval) {
|
||||
super(resourceType, samplingInterval);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -26,11 +26,11 @@ public class ResourceLeakDetectorBenchmark extends AbstractMicrobenchmark {
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
detector = new ResourceLeakDetector<>(getClass(), 128, Long.MAX_VALUE);
|
||||
detector = new ResourceLeakDetector<>(getClass(), 128);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object open() {
|
||||
return detector.open(DUMMY);
|
||||
return detector.track(DUMMY);
|
||||
}
|
||||
}
|
||||
|
@ -32,8 +32,7 @@ public class ResourceLeakDetectorRecordBenchmark extends AbstractMicrobenchmark
|
||||
private int recordTimes;
|
||||
private ResourceLeakDetector.Level level;
|
||||
|
||||
ResourceLeakDetector<Object> detector = new ResourceLeakDetector<Object>(
|
||||
Object.class, 1, Integer.MAX_VALUE) {
|
||||
ResourceLeakDetector<Object> detector = new ResourceLeakDetector<Object>(Object.class, 1) {
|
||||
@Override
|
||||
protected void reportTracedLeak(String resourceType, String records) {
|
||||
// noop
|
||||
|
Loading…
Reference in New Issue
Block a user