The java.lang.foreign.ValueLayout
API that was introduced in Java 22 provides a convenient method for declaring the layout of manually-managed memory so you don’t need to do byte arithmetic on reads & writes. There are layouts available for all the common primitive types, and many have an _UNALIGNED
variant. To take the example of JAVA_LONG
, here is how it is described:
A value layout constant whose size is the same as that of a Java long, (platform-dependent) byte alignment set to
ADDRESS.byteSize()
, and byte order set toByteOrder.nativeOrder()
.
Here is how JAVA_LONG_UNALIGNED
is described:
An unaligned value layout constant whose size is the same as that of a Java long and byte order set to
ByteOrder.nativeOrder()
.
These descriptions sound very similar to me, so I’m not sure what the difference is. However, I have noticed one difference in practice: _UNALIGNED
variants do not support the atomic VarHandle.compareAndSet
APIs, as also documented in this answer.
What is the benefit to using _UNALIGNED
, then? Is it only really relevant if you are dealing with memory allocated in that way by some other application, and if you’re allocating the memory yourself you should always used the aligned memory layout?