sclass InvestigateNonTransientGraph { MetaTransformer mt; Map back = identityHashMap(); new MultiSet objectsBySize; new MultiMap objectsByClass; new MultiSet objectsByDynClass; *() { mt = metaTransformer_collectionAndMap(); mt.add(new MTSH_nonTransientFields); mt.avoidCycles(); mt.markPointer = (a, b) -> { putIfNotThere(back, b, a); }; } void scan(O root) { VStack.Computable v = mt.new visit_vstackComputable(o -> { objectsBySize.add(o.getClass(), clampToInt(unsafe_sizeOf(o))); objectsByClass.put(o.getClass(), o); if (o instanceof DynamicObject) objectsByDynClass.add(shortDynClassName(o)); }, root); vstackCompute(v); } void printResults() { print("Seen objects: " + n2(mt.seen)); print(); print("Most popular classes:"); print(multiSetToLines(multiMapToMultiSet(objectsByClass), 20)); print(); print("Total bytes per class:"); print(multiSetToLines(objectsBySize, 20)); if (!empty(objectsByDynClass)) { print("Total bytes per dynamic class:"); print(multiSetToLines(objectsByDynClass, 20)); } } L biggestOfClass(Class c) { ret sortedByCalculatedFieldDesc unsafe_objectSize(objectsByClass.get(c)); } }