This class could be used for any object contents/memory layout printing.
How shall we find a memory layout of an object?
- Obtain all object fields, including its parent class fields, recursively calling Class.getDeclaredFields on the class and its superclasses.
- For all non-static fields (Field.getModifiers() & Modifiers.STATIC) obtain an offset of a field in its parent object using Unsafe.objectFieldOffset and a shallow field size : predefined values for primitives and either 4 or 8 bytes for object references.
- For arrays, call Unsafe.arrayBaseOffset and Unsafe.arrayIndexScale. The total shallow size of an array would be offset + scale * Array.getLength(array) and, of course, a reference to the array itself (see previous point).
- Do not forget that there may be a circular references in the object graph, so you will need to track all previously visited objects (IdentityHashMap is recommended for such cases).