Improve object tracking configurations

This commit is contained in:
mcrcortex
2024-08-06 23:15:57 +10:00
parent 377c51f365
commit 082143ed15

View File

@@ -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,7 +17,9 @@ 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;
this.ref.cleanable.clean(); if (TRACK_OBJECT_ALLOCATIONS) {
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;
public static Ref register(Object obj) { static {
String clazz = obj.getClass().getName(); if (TRACK_OBJECT_ALLOCATIONS) {
Throwable trace; cleaner = Cleaner.create();
if (true) {
trace = new Throwable();
trace.fillInStackTrace();
} else { } else {
trace = null; cleaner = null;
} }
}
public static Ref register(Object obj) {
boolean[] freed = new boolean[1]; boolean[] freed = new boolean[1];
var clean = cleaner.register(obj, ()->{ Cleaner.Cleanable cleanable = null;
if (!freed[0]) { if (TRACK_OBJECT_ALLOCATIONS) {
System.err.println("Object named: "+ clazz+" was not freed, location at:\n"); String clazz = obj.getClass().getName();
if (trace != null) { Throwable trace;
trace.printStackTrace(); if (TRACK_OBJECT_ALLOCATION_STACKS) {
} else { trace = new Throwable();
System.err.println("Enable error tracing"); trace.fillInStackTrace();
} } else {
System.err.flush(); trace = null;
} }
}); cleanable = cleaner.register(obj, () -> {
return new Ref(clean, freed); if (!freed[0]) {
System.err.println("Object named: " + clazz + " was not freed, location at:\n");
if (trace != null) {
trace.printStackTrace();
} else {
System.err.println("Enable allocation stack tracing");
}
System.err.flush();
}
});
}
return new Ref(cleanable, freed);
} }
} }