Many hardware implementations require the accesses to data to be aligned, that is make sure that all accesses of N byte width are done on addresses that are integer multiples of N. Even when this is not specifically required for the plain accesses to data, special operations (notably, atomic operations), usually have alignment constraints too.

For example, x86 is generally receptive to misaligned reads and writes, and misaligned CAS that spans two cache lines at once still works, but it tanks the throughput performance. Other architectures would just plainly refuse to do such atomic operation, yielding a SIGBUS or another hardware exception. x86 also does not guarantee access atomicity for values that span multiple cache lines, which is a possibility when access is misaligned. Java specification, on the other hand, requires access atomicity for most types, and definitely for all volatile accesses.

So, if we have the long field in Java object, and it takes 8 bytes in memory, we have to make sure it is aligned by 8 bytes for performance reasons. Or even for correctness reasons, if that field is volatile . In a simple approach, two things need to happen for this to hold true: the field offset inside the object should be aligned by 8 bytes, and the object itself should be aligned by 8 bytes. That is indeed what we shall see if we peek into java.lang.Long instance:

$ java -jar jol-cli.jar internals java.lang.Long # Running 64-bit HotSpot VM. # Using compressed oop with 3-bit shift. # Using compressed klass with 3-bit shift. # Objects are 8 bytes aligned. # Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] # Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] java.lang.Long object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 01 00 00 00 4 4 (object header) 00 00 00 00 8 4 (object header) ce 21 00 f8 12 4 (alignment/padding gap) 16 8 long Long.value 0 Instance size: 24 bytes Space losses: 4 bytes internal + 0 bytes external = 4 bytes total

Here, the value field itself is at offset 16 (it is multiple of 8), and the object is aligned by 8.

Even if there are no fields that require special treatment, there are still object headers that also need to be accessed atomically. It is technically possible to align the majority of Java objects by 4 bytes, rather by 8 bytes, however the runtime work required to pull that off is quite immense.

So, in Hotspot, the minimum object alignment is 8 bytes. Can it be larger, though? Sure it can, there is the VM option for that: -XX:ObjectAlignmentInBytes . And it comes with two consequences, one negative and one positive.

Instance Sizes Get Large Of course, once the alignment gets larger, it means that the average space wasted per-object would also increase. See, for example, the object alignment increased to 16 and 128 bytes: $ java -XX:ObjectAlignmentInBytes=16 -jar jol-cli.jar internals java.lang.Long java.lang.Long object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 01 00 00 00 4 4 (object header) 00 00 00 00 8 4 (object header) c8 10 01 00 12 4 (alignment/padding gap) 16 8 long Long.value 0 24 8 (loss due to the next object alignment) Instance size: 32 bytes Space losses: 4 bytes internal + 8 bytes external = 12 bytes total $ java -XX:ObjectAlignmentInBytes=128 -jar jol-cli.jar internals java.lang.Long java.lang.Long object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 01 00 00 00 4 4 (object header) 00 00 00 00 8 4 (object header) a8 24 01 00 12 4 (alignment/padding gap) 16 8 long Long.value 0 24 104 (loss due to the next object alignment) Instance size: 128 bytes Space losses: 4 bytes internal + 104 bytes external = 108 bytes total Hell, 128 bytes per instance that only has 8 bytes of useful data seems excessive. Why would anyone do that?