> From: "Joe Mwangi" <[email protected]>
> To: "valhalla-dev" <[email protected]>
> 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 

Reply via email to