Observations and Questions on Flattening Behavior and Memory Alignment in Value Objects
Remi Forax
forax at univ-mlv.fr
Sun Oct 26 14:38:17 UTC 2025
> From: "Joe Mwangi" <joemwangimburu at gmail.com>
> To: "valhalla-dev" <valhalla-dev at openjdk.org>
> Sent: Sunday, October 26, 2025 2:30:52 PM
> Subject: Observations and Questions on Flattening Behavior and Memory Alignment
> in Value Objects
> Hi Valhalla Development Team,
Hello Joe,
i'm not part of the implementation team (i'm part of the spec team), but i can answer to some of your questions,
> Thank you for providing the latest build for testing progress on value objects
> in the JVM. I’ve been running a few experiments to understand the behavior of
> custom value types and their memory characteristics, and I must say I’m very
> impressed by the implementation so far. Memory usage appears significantly
> reduced in many cases (sometimes to nearly ¾ of the original).
> Here’s a simple test I used:
> public class ValhallaTest { value record PointRecord ( short x, short y, short
> z) {} void main () throws InterruptedException { Thread.sleep( 9000 ); // allow
> time to attach VisualVM System.out.println( "Starting" ); int size = 10_000_000
> ; var pointRecords = new PointRecord [size]; for ( int i = 0 ; i < size; i++) {
> pointRecords[i] = new PointRecord (( short ) 2 , ( short ) 2 , ( short ) 3 ); }
> Thread.sleep( 20000 ); } }
> Using VisualVM, I inspected live objects and heap usage, with the following
> observations:
> 1.
> No individual PointRecord objects were detected — only the PointRecord[] array,
> confirming full flattening (no identity objects).
> 2.
> PointRecord(short, short, short) logically occupies 6 bytes, but the array
> reports 80 000 000 B for 10 M elements → 8 bytes per element, suggesting
> alignment to 64 bits.
it's short + short + short + byte (for null) + alignment, hence 64 bits.
1.
PointRecord(short x, short y) → 40 000 000 B → 4 bytes per element.
2.
PointRecord(byte x) → 20 000 000 B → 2 bytes per element.
> It appears the prototype aligns flattened array elements to the smallest power of two ≥ the logical size (not just 4-byte boundaries). Beyond 64 bits (≥ 8 bytes), flattening seems to stop, possibly reverting to identity semantics, which makes sense given mutation and tearing concerns.
So it's more than you need to add a bit (a byte) representing null and then it has to be a power of two (alignment) because you want to read the location in one read/write to avoid tearing.
> A few questions came up from these results:
1.
Will arrays need to be immutable to guarantee flattening for value elements larger than 64 bits? Think about parsing large files, where a large array with larger sized value object will be important, hence mutable array being key, and then do simd parsing.
The array needs to have non-null elements, and you need a way to opt-out of atomicity (allow tearing).
The exact way to do the latter is still in flux.
About using simd, there is an issue because you can read/write using simd but then you need to extract the value from the simd register to a general purpose register and this is actually quite slow,
so the Hotspot does not do that.
> 1.
> 2.
> Since value objects are scalarized across stack calls, will there be tooling to
> analyze whether scalarization actually occurs (e.g., register-based limits
> determined by the JVM, if not enough register space, value object gains
> identity)?
as far as i know, c2 (the only JIT that optimize value classes) will scalarize depending on the size of the instance but not depending on if you have not enough registers, the registers will be spilled on stack in that case.
> 1.
> 2.
> In C, struct size can be predicted from field types. For Java value objects,
> since layout is JVM-dependent, is there a plan for tooling (perhaps jcmd or JFR
> integration) to expose explicit size/layout information beyond array
> inspection? The default above example shows that a 6 bytes size value object is
> actually 8 bytes, but in C, it shall remain 6 byte size.
you can use -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlineLayout but it only works for fields, not for arrays.
> Overall, this is very exciting work. The model feels both efficient and
> semantically robust, offering a fresh take compared to languages that rely on
> purely compile-time memory determinism. I’ll continue exploring performance and
> GC interaction aspects later, but even this preliminary testing shows
> remarkable promise.
> Thanks again to the entire team for the great work.
> Kind regards,
> Joe Mwangi
regards,
Rémi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-dev/attachments/20251026/707ff71b/attachment.htm>
More information about the valhalla-dev
mailing list