diff --git a/falco-benchmarks/src/test/java/net/onelitefeather/falco/benchmark/instance/ChunkFootprintTest.java b/falco-benchmarks/src/test/java/net/onelitefeather/falco/benchmark/instance/ChunkFootprintTest.java
index cc4c866..bd3ebd8 100644
--- a/falco-benchmarks/src/test/java/net/onelitefeather/falco/benchmark/instance/ChunkFootprintTest.java
+++ b/falco-benchmarks/src/test/java/net/onelitefeather/falco/benchmark/instance/ChunkFootprintTest.java
@@ -19,8 +19,10 @@
import org.openjdk.jol.info.GraphLayout;
import org.openjdk.jol.vm.VM;
+import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashSet;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
@@ -334,6 +336,26 @@ class ChunkFootprintTest {
*/
private static final int TRACKER_CHUNKS = 16;
+ /**
+ * How many classes may carry a negative count before the comparison is treated as broken.
+ *
+ * The per class figures are differences between two walks — everything the chunk and its instance
+ * retain, minus what the instance retains alone. A count below zero cannot be a property of the
+ * chunk, because a set of objects that exist because the chunk exists has no negative
+ * cardinality. It means the instance grew between the two walks, and the classes seen doing that
+ * are the JVM's own bookkeeping: {@code java.io.FileCleanable} when a file handle is registered,
+ * {@code byte[]} when a string is built. Comparing such a row states nothing about either chunk,
+ * so it is skipped and its bytes are carried into the total instead.
+ *
+ *
+ * The limit is what keeps that from turning into a way of passing. Skipping one or two rows loses
+ * nothing; skipping many would mean the walk disagreed with itself wholesale, and the answer to
+ * that is a failure, not a comparison of whatever survived. Two is the observed ceiling: the
+ * failures on 2026-08-03 carried exactly one such class each.
+ *
+ */
+ private static final int UNMEASURABLE_CLASS_LIMIT = 2;
+
/**
* The width of the label column of the breakdown table.
*/
@@ -885,11 +907,20 @@ private static void assertOnlyTheDeclaredClassesDiffer(Footprint minestom, Chunk
classNames.addAll(declared.keySet());
long declaredBytes = 0;
+ long unmeasuredBytes = 0;
+ final List unmeasured = new ArrayList<>();
for (String className : classNames) {
if (className.startsWith(minestomType) || className.startsWith(falcoType)) {
continue;
}
+ if (minestom.objectsOf(className) < 0 || falcoSide.objectsOf(className) < 0) {
+ unmeasured.add(className + ": Minestom " + minestom.objectsOf(className) + " objects / "
+ + minestom.bytesOf(className) + " B, Falco " + falcoSide.objectsOf(className)
+ + " / " + falcoSide.bytesOf(className) + " B");
+ unmeasuredBytes += falcoSide.bytesOf(className) - minestom.bytesOf(className);
+ continue;
+ }
final Declared row = declared.get(className);
if (row == null) {
@@ -920,10 +951,21 @@ private static void assertOnlyTheDeclaredClassesDiffer(Footprint minestom, Chunk
+ " bytes, so it holds the declared objects at a size nobody declared");
declaredBytes += expectedBytes - minestom.bytesOf(className);
}
- assertEquals(declaredBytes, falcoSide.bytes() - minestom.bytes(),
+ if (!unmeasured.isEmpty()) {
+ System.out.println(context + ": " + unmeasured.size() + " class(es) carried a negative count "
+ + "and were left out of the comparison, together worth " + unmeasuredBytes
+ + " B of the total difference: " + String.join("; ", unmeasured));
+ }
+ assertTrue(unmeasured.size() <= UNMEASURABLE_CLASS_LIMIT,
+ context + ": " + unmeasured.size() + " classes carried a negative count. Skipping that many "
+ + "stops this from being a comparison at all — the exclusion exists for the one or "
+ + "two bookkeeping classes the JVM adds between the two walks, not for a walk that "
+ + "disagreed with itself wholesale: " + String.join("; ", unmeasured));
+ assertEquals(declaredBytes + unmeasuredBytes, falcoSide.bytes() - minestom.bytes(),
context + ": the two chunks differ by " + (falcoSide.bytes() - minestom.bytes())
+ " bytes while the classes the plan declared account for " + declaredBytes
- + " and every other class was just asserted equal. The two do not add up, which "
+ + ", the classes no walk could measure for " + unmeasuredBytes
+ + ", and every other class was just asserted equal. The three do not add up, which "
+ "is a statement about the walk rather than about the chunk: the per class table "
+ "of a footprint has to sum to the total that footprint reports.");
assertEquals(ClassLayout.parseInstance(minestomChunk).instanceSize(),