Adding explicit extra space (explicit padding) to validate alignment
Let’s consider the following C-like struct (let’s denote this as Case 1):
StructLayout product = MemoryLayout.structLayout(
ValueLayout.JAVA_INT.withName(“sku”),
ValueLayout.JAVA_CHAR.withName(“energy”),
ValueLayout.JAVA_BYTE.withName(“weight”));
The product size returned via byteSize() is 7 bytes (4 + 2 + 1). The product alignment returned via byteAlignment() is 4 (the greater alignment of 4, 2, and 1). The byte offset of each member layout returned by byteOffset() is as follows:
long boSku = product.byteOffset( // 0
PathElement.groupElement(“sku”));
long boEnergy = product.byteOffset( // 4
PathElement.groupElement(“energy”));
long boWeight = product.byteOffset( // 6
PathElement.groupElement(“weight”));
If we represent this via a diagram we obtain the following figure:

Figure 7.17 – The representation of the struct
Everything looks fine, so we can go further. Now, let’s use the same struct, but we arrange the member layouts as follows (let’s denote this as Case 2):
StructLayout product = MemoryLayout.structLayout(
ValueLayout.JAVA_CHAR.withName(“energy”),
ValueLayout.JAVA_INT.withName(“sku”),
ValueLayout.JAVA_BYTE.withName(“weight”));
First, we place the energy (char) at offset 0. Since energy (char) consumes 2 bytes, it is followed by sku (int) at offset 2. Since sku (int) consumes 4 bytes, it is followed by weight (byte). But, is this the correct logic? As you can see in the following figure (left-hand side) this logic is incorrect, because we have an invalid alignment error at offset 2 for the sku (int).

Figure 7.18 – Incorrect/correct padding
The alignment of energy (char) is 2, so it can start only on 0, 2, 4, …. Since energy (char) is the first, we start with it on offset 0. Next, the alignment of sku (int) is 4, so it can start only on 0, 4, 8, … That is why the start address of sku is at 4, and not at 2. Finally, the alignment of weight (byte) is 1, so it can go after sku (int) at offset 8.So, by following the alignment rules, we conclude that the size of product in 9, not 7. At this point, we know that, for aligning sku (int), we should add a padding of 2 bytes (16 bits) at offset 2, so let’s do it:
StructLayout product = MemoryLayout.structLayout(
ValueLayout.JAVA_CHAR.withName(“energy”),
MemoryLayout.paddingLayout(16),
ValueLayout.JAVA_INT.withName(“sku”),
ValueLayout.JAVA_BYTE.withName(“weight”));
Next, let’s assume that we want to repeat this C-like struct 2 times (or, n times). For this, we nest the struct in a sequence layout as follows (let’s denote this as Case 3):
SequenceLayout product = MemoryLayout.sequenceLayout(
2, MemoryLayout.structLayout(
ValueLayout.JAVA_CHAR.withName(“energy”),
MemoryLayout.paddingLayout(16),
ValueLayout.JAVA_INT.withName(“sku”),
ValueLayout.JAVA_BYTE.withName(“weight”)));
This time, the code fails with an exception as UnsupportedOperationException: Alignment requirements for layout c16(energy) do not match stride 72. What’s happening now? Well, the first struct instance lies out from offset 0 to offset 8, and, conforming to our code, the second struct lies out from offset 9 to offset 18, as in the following figure (top diagram):

Figure 7.19 – Calculating stride
But, this is not correct, because the second instance of the struct (and the third, fourth, and so on) doesn’t follow the alignment rules. The alignment of the struct is 4, so an instance of struct should be at 0, 4, 8, 12, 16, …, but not at 9. This means that we need to calculate stride which gives us the minimum byte-distance between two member layouts – here, two instances of our struct.We have that the size of the struct instance is 9 and its alignment is 4. So, we need to find the offset evenly divisible by 4 which is greater and closest to 9. This is 12. Since stride is 12, it means that the second instance of struct starts at offset 12. We need to add a padding of 3 (12-9) bytes:
SequenceLayout product = MemoryLayout.sequenceLayout(
2, MemoryLayout.structLayout(
ValueLayout.JAVA_CHAR.withName(“energy”),
MemoryLayout.paddingLayout(16),
ValueLayout.JAVA_INT.withName(“sku”),
ValueLayout.JAVA_BYTE.withName(“weight”),
MemoryLayout.paddingLayout(24)));
Done! As you can see, the order of member layouts counts a lot. By being aware of the size, alignment, stride, and padding we can optimize the memory allocation by simply arranging the member layouts in a proper order that requires 0 or minimum padding.In the bundled code, you can find more examples of permutating the member layout of our struct.