every object you allocate drags a header around with it. 12 bytes on 64 bit hotspot before a single field of yours shows up. compact object headers cut that to 8.
java -XX:+UseCompactObjectHeaders -jar server.jar
thats it. no code changes, no rebuild, nothing else on the box has to care.
why minecraft specifically
think about what one tick allocates. block positions. item stacks. vectors. NBT tags all the way down, packets by the thousand. none of it is big and thats the whole problem, the smaller the object the more of it is just header doing nothing for you.
quick math. class with two ints. old headers thats 12 + 8 = 20, rounds up to 24 because everything gets padded to 8 anyway. compact headers, 8 + 8 = 16, nothing wasted. same object a third smaller and the third you cut was never your data to begin with.
smaller objects, smaller live set. smaller live set, less for the GC to walk and copy every single cycle. thats the part you actually feel as TPS. the JEP says 10-20% less heap and its being conservative, amazon shipped it across prod services and got 22% plus 8-11% more throughput on top.
which jdk
- 25+ just
-XX:+UseCompactObjectHeaders - 24 shove
-XX:+UnlockExperimentalVMOptionsin front of it, was still experimental back then - 27 on by default so you can forget the flag exists.
-XX:-UseCompactObjectHeadersif you somehow want it off
on 25 or 26 go turn it on. still waiting on someone to give me a real reason not to.