Improve object tracking configurations
This commit is contained in:
@@ -3,6 +3,10 @@ package me.cortex.voxy.common.util;
|
|||||||
import java.lang.ref.Cleaner;
|
import java.lang.ref.Cleaner;
|
||||||
|
|
||||||
public abstract class TrackedObject {
|
public abstract class TrackedObject {
|
||||||
|
//TODO: maybe make this false? for performance overhead?
|
||||||
|
public static final boolean TRACK_OBJECT_ALLOCATIONS = System.getProperty("voxy.ensureTrackedObjectsAreFreed", "true").equals("true");
|
||||||
|
public static final boolean TRACK_OBJECT_ALLOCATION_STACKS = System.getProperty("voxy.trackObjectAllocationStacks", "false").equals("true");
|
||||||
|
|
||||||
private final Ref ref;
|
private final Ref ref;
|
||||||
public TrackedObject() {
|
public TrackedObject() {
|
||||||
this.ref = register(this);
|
this.ref = register(this);
|
||||||
@@ -13,8 +17,10 @@ public abstract class TrackedObject {
|
|||||||
throw new IllegalStateException("Object " + this + " was double freed.");
|
throw new IllegalStateException("Object " + this + " was double freed.");
|
||||||
}
|
}
|
||||||
this.ref.freedRef[0] = true;
|
this.ref.freedRef[0] = true;
|
||||||
|
if (TRACK_OBJECT_ALLOCATIONS) {
|
||||||
this.ref.cleanable.clean();
|
this.ref.cleanable.clean();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public abstract void free();
|
public abstract void free();
|
||||||
|
|
||||||
@@ -30,28 +36,38 @@ public abstract class TrackedObject {
|
|||||||
|
|
||||||
public record Ref(Cleaner.Cleanable cleanable, boolean[] freedRef) {}
|
public record Ref(Cleaner.Cleanable cleanable, boolean[] freedRef) {}
|
||||||
|
|
||||||
private static final Cleaner cleaner = Cleaner.create();
|
private static final Cleaner cleaner;
|
||||||
|
static {
|
||||||
|
if (TRACK_OBJECT_ALLOCATIONS) {
|
||||||
|
cleaner = Cleaner.create();
|
||||||
|
} else {
|
||||||
|
cleaner = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
public static Ref register(Object obj) {
|
public static Ref register(Object obj) {
|
||||||
|
boolean[] freed = new boolean[1];
|
||||||
|
Cleaner.Cleanable cleanable = null;
|
||||||
|
if (TRACK_OBJECT_ALLOCATIONS) {
|
||||||
String clazz = obj.getClass().getName();
|
String clazz = obj.getClass().getName();
|
||||||
Throwable trace;
|
Throwable trace;
|
||||||
if (true) {
|
if (TRACK_OBJECT_ALLOCATION_STACKS) {
|
||||||
trace = new Throwable();
|
trace = new Throwable();
|
||||||
trace.fillInStackTrace();
|
trace.fillInStackTrace();
|
||||||
} else {
|
} else {
|
||||||
trace = null;
|
trace = null;
|
||||||
}
|
}
|
||||||
boolean[] freed = new boolean[1];
|
cleanable = cleaner.register(obj, () -> {
|
||||||
var clean = cleaner.register(obj, ()->{
|
|
||||||
if (!freed[0]) {
|
if (!freed[0]) {
|
||||||
System.err.println("Object named: " + clazz + " was not freed, location at:\n");
|
System.err.println("Object named: " + clazz + " was not freed, location at:\n");
|
||||||
if (trace != null) {
|
if (trace != null) {
|
||||||
trace.printStackTrace();
|
trace.printStackTrace();
|
||||||
} else {
|
} else {
|
||||||
System.err.println("Enable error tracing");
|
System.err.println("Enable allocation stack tracing");
|
||||||
}
|
}
|
||||||
System.err.flush();
|
System.err.flush();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return new Ref(clean, freed);
|
}
|
||||||
|
return new Ref(cleanable, freed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user