|
|
@ -40,65 +40,38 @@ public class CoalMine {
|
|
|
|
static void setup(boolean enabled) {
|
|
|
|
static void setup(boolean enabled) {
|
|
|
|
List<ObjectInspector> inspectors = new ArrayList<>(LeakCanary.getConfig().getObjectInspectors());
|
|
|
|
List<ObjectInspector> inspectors = new ArrayList<>(LeakCanary.getConfig().getObjectInspectors());
|
|
|
|
|
|
|
|
|
|
|
|
inspectors.add(new ObjectInspector() {
|
|
|
|
// https://square.github.io/leakcanary/recipes/#identifying-leaking-objects-and-labeling-objects
|
|
|
|
@Override
|
|
|
|
for (Class<?> clazz : new Class<?>[]{SimpleTask.class, TwoStateOwner.class, RunnableEx.class})
|
|
|
|
public void inspect(@NonNull ObjectReporter reporter) {
|
|
|
|
inspectors.add(new ObjectInspector() {
|
|
|
|
String clazz = SimpleTask.class.getName();
|
|
|
|
@Override
|
|
|
|
reporter.whenInstanceOf(clazz, new Function2<ObjectReporter, HeapObject.HeapInstance, Unit>() {
|
|
|
|
public void inspect(@NonNull ObjectReporter reporter) {
|
|
|
|
@Override
|
|
|
|
String className = clazz.getName();
|
|
|
|
public Unit invoke(ObjectReporter reporter, HeapObject.HeapInstance instance) {
|
|
|
|
reporter.whenInstanceOf(className, new Function2<ObjectReporter, HeapObject.HeapInstance, Unit>() {
|
|
|
|
HeapField fname = instance.get(clazz, "name");
|
|
|
|
@Override
|
|
|
|
if (fname != null) {
|
|
|
|
public Unit invoke(ObjectReporter reporter, HeapObject.HeapInstance instance) {
|
|
|
|
String name = fname.getValue().readAsJavaString();
|
|
|
|
HeapField hfName = instance.get(className, "name");
|
|
|
|
reporter.getNotLeakingReasons().add("name=" + name);
|
|
|
|
if (hfName != null) {
|
|
|
|
|
|
|
|
String label = hfName.getValue().readAsJavaString();
|
|
|
|
|
|
|
|
reporter.getLabels().add("name=" + label);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Could be different class loader
|
|
|
|
|
|
|
|
if (className.equals(SimpleTask.class.getName())) {
|
|
|
|
|
|
|
|
HeapField hfStarted = instance.get(className, "started");
|
|
|
|
|
|
|
|
if (hfStarted != null) {
|
|
|
|
|
|
|
|
Long started = hfStarted.getValue().getAsLong();
|
|
|
|
|
|
|
|
if (started != null) {
|
|
|
|
|
|
|
|
String label = (started == 0 ? null : new Date(started).toString());
|
|
|
|
|
|
|
|
reporter.getLabels().add("started=" + label);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
HeapField fstarted = instance.get(clazz, "started");
|
|
|
|
});
|
|
|
|
if (fstarted != null) {
|
|
|
|
}
|
|
|
|
Long started = fstarted.getValue().getAsLong();
|
|
|
|
});
|
|
|
|
if (started != null)
|
|
|
|
|
|
|
|
reporter.getNotLeakingReasons().add("started=" + new Date(started));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inspectors.add(new ObjectInspector() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void inspect(@NonNull ObjectReporter reporter) {
|
|
|
|
|
|
|
|
String clazz = TwoStateOwner.class.getName();
|
|
|
|
|
|
|
|
reporter.whenInstanceOf(clazz, new Function2<ObjectReporter, HeapObject.HeapInstance, Unit>() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public Unit invoke(ObjectReporter reporter, HeapObject.HeapInstance instance) {
|
|
|
|
|
|
|
|
HeapField fname = instance.get(clazz, "name");
|
|
|
|
|
|
|
|
if (fname != null) {
|
|
|
|
|
|
|
|
String name = fname.getValue().readAsJavaString();
|
|
|
|
|
|
|
|
reporter.getNotLeakingReasons().add("name=" + name);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inspectors.add(new ObjectInspector() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void inspect(@NonNull ObjectReporter reporter) {
|
|
|
|
|
|
|
|
String clazz = RunnableEx.class.getName();
|
|
|
|
|
|
|
|
reporter.whenInstanceOf(clazz, new Function2<ObjectReporter, HeapObject.HeapInstance, Unit>() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public Unit invoke(ObjectReporter reporter, HeapObject.HeapInstance instance) {
|
|
|
|
|
|
|
|
HeapField fname = instance.get(clazz, "name");
|
|
|
|
|
|
|
|
if (fname != null) {
|
|
|
|
|
|
|
|
String name = fname.getValue().readAsJavaString();
|
|
|
|
|
|
|
|
reporter.getNotLeakingReasons().add("name=" + name);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LeakCanary.Config config = LeakCanary.getConfig().newBuilder()
|
|
|
|
LeakCanary.Config config = LeakCanary.getConfig().newBuilder()
|
|
|
|
.dumpHeap(enabled && BuildConfig.DEBUG)
|
|
|
|
.dumpHeap(enabled && BuildConfig.DEBUG)
|
|
|
|