Are Java records similar to C# structs? I mean, if they are stack allocated instead of using references like classes, that are allocated on heap.
No. Records are just a simpler way of writing value classes, but are not allocated any differently than normal objects.
(This is not to say that such types aren't in progress -- they are -- but records are not this feature.)
Java records and stack-allocated types are separate features (with stack-allocated types being a planned upcoming feature). According to the current plan, a record class that meets the requirements can be written to be one of these stack-allocated types, but not all record types can or will be.
Records
Records were delivered in Java 16 as a result of JEP 395: Records, after preview iterations in Java 14 & 15 per JEP 359 and jep 384. Aside from a number of record-specific restrictions, records mostly behave like normal classes. They are also heap allocated like normal classes.
Value types
As of this writing (September 2022) there are currently proposals to support "value objects" that may be (but are not required to be) allocated on the heap, rather than on the stack. These include JEP draft: Value Objects (Preview) and JEP 401: Primitive Classes. Value types lack identity, and a stated goal of the value objects JEP is to support (though not require) inlining value objects where feasible:
At runtime, the HotSpot JVM will prefer inlining value objects where feasible, in particular for JIT-compiled method calls and local operations. An inlined value object is encoded directly with its field values, avoiding any overhead from object headers, indirections, or heap allocation.
The "HotSpot implementation" section of the value object & primitive class JEPs both indicate when HotSpot will allocate these types on the stack or heap. This depends on whether the C1 (client) or C2 (server) compiler is used.
- In the interpreter and C1, value objects on the stack are also encoded as regular heap objects.
- In C2, value objects on the stack are typically scalarized when stored or passed with concrete value class types. Scalarization effectively encodes each field as a separate variable, with an additional variable encoding null; no heap allocation is needed. Methods with value-class-typed parameters support both a pointer-based entry point (for interpreter and C1 calls) and a scalarized entry point (for C2-to-C2 calls). Value objects are allocated on the heap when they need to be viewed as values of a supertype of the value class, or when stored in fields or arrays.
- In the interpreter and C1, primitive values on the stack are represented as value objects. Each read of a primitive-typed field or array allocates a heap object.
- In C2, primitive values on the stack are scalarized, effectively encoding each field as a separate variable. Methods with Q-typed parameters support both a pointer-based entry point (for interpreter and C1 calls) and a scalarized entry point (for C2-to-C2 calls). Value objects are also scalarized when working with the primitive class's reference type. Heap allocations occur where any other supertype is used.
Value-typed records
Record classes will be able to be declared as value or primitive types to support this sort of stack allocation, but are not required to be.
No, and they are not more heap memory efficient in any way (many people somehow suspect / assume they are).
© 2022 - 2024 — McMap. All rights reserved.