import java.lang.reflect.Field; /** * Where does the first field of an object start? Code that hard-codes "12 bytes of header" gets this wrong * on JDK 27. Run with: java --sun-misc-unsafe-memory-access=allow Offsets.java * (The flag silences the JDK 24+ warning about sun.misc.Unsafe; nothing here reads or writes memory.) */ public class Offsets { static class P { long id; int priceCents; int stock; boolean active; Object sku; } @SuppressWarnings("removal") public static void main(String[] args) throws Exception { Field f = sun.misc.Unsafe.class.getDeclaredField("theUnsafe"); f.setAccessible(true); sun.misc.Unsafe u = (sun.misc.Unsafe) f.get(null); System.out.println("java " + System.getProperty("java.version") + " compact headers: " + java.lang.management.ManagementFactory .getPlatformMXBean(com.sun.management.HotSpotDiagnosticMXBean.class) .getVMOption("UseCompactObjectHeaders").getValue()); long first = Long.MAX_VALUE; for (Field x : P.class.getDeclaredFields()) { long off = u.objectFieldOffset(x); first = Math.min(first, off); System.out.printf(" %-11s offset %2d%n", x.getName(), off); } System.out.println(" first field starts at byte " + first + " (so the header is at most " + first + " bytes)"); System.out.println(" a hard-coded 12-byte header would be " + (first == 12 ? "right" : "WRONG") + " here"); } }