- 所有已知的子接口:
GroupLayoutPREVIEW,PaddingLayoutPREVIEW,SequenceLayoutPREVIEW,StructLayoutPREVIEW,UnionLayoutPREVIEW,ValueLayoutPREVIEW,ValueLayout.OfAddressPREVIEW,ValueLayout.OfBooleanPREVIEW,ValueLayout.OfBytePREVIEW,ValueLayout.OfCharPREVIEW,ValueLayout.OfDoublePREVIEW,ValueLayout.OfFloatPREVIEW,ValueLayout.OfIntPREVIEW,ValueLayout.OfLongPREVIEW,ValueLayout.OfShortPREVIEW
MemoryLayout 是 Java 平台的预览 API。
ValueLayout PREVIEW ) 和 padding layouts ,顾名思义,它们用于表示内存段的一部分,其内容应被忽略,并且主要出于对齐原因而存在(参见 paddingLayout(long) )。 ValueLayout 中定义了一些常用值布局常量PREVIEW 类。
更复杂的布局可以从更简单的布局中派生出来:a sequence layout 表示一个或多个元素布局的重复(参见 SequenceLayout PREVIEW ); group layout 表示(通常)异构成员布局的聚合(参见 GroupLayout PREVIEW ).
布局可以选择与 name 相关联。构造layout paths 时可以参考布局名称。
考虑以下 C 中的结构声明:
typedef struct {
char kind;
int value;
} TaggedValues[5];
SequenceLayout taggedValues = MemoryLayout.sequenceLayout(5,
MemoryLayout.structLayout(
ValueLayout.JAVA_BYTE.withName("kind"),
MemoryLayout.paddingLayout(24),
ValueLayout.JAVA_INT.withName("value")
)
).withName("TaggedValues");
大小、对齐和字节顺序
所有布局都有尺寸;值和填充布局的布局大小始终明确表示;这意味着无论在哪个平台上使用,布局描述总是具有相同的位大小。对于派生布局,大小计算如下:- 对于元素布局为E且大小为L的序列布局S,S的大小是E的大小乘以L
- 对于具有成员布局 M1、M2、...Mn 的组布局 G,其大小分别为 S1、S2、...Sn,G 的大小为 S1 + S2 + ... + Sn 或 max(S1, S2, ... Sn) 取决于组是 struct 还是 union , 分别
此外,所有布局都有一个 natural alignment 可以推断如下:
- 对于 padding 布局 L ,自然对齐是 1,不管它的大小;也就是说,在没有显式对齐约束的情况下,填充布局不应影响它嵌套到的组布局的对齐约束
- 对于大小为 N 的值布局 L,L 的自然对齐方式为 N
- 对于元素布局为 E 的序列布局 S , S 的自然对齐是 E 的自然对齐
- 对于组布局 G 和成员布局 M1 , M2 , ... Mn 其对齐方式分别为 A1 , A2 , ... An , G 的自然对齐方式为 max(A1, A2 ... An)
withBitAlignment(long) ),这对于描述超对齐布局很有用。
所有值布局都有一个 explicit 字节顺序(请参阅 ByteOrder ),它是在创建布局时设置的。
布局路径
layout path 源自 root 布局(通常是组布局或序列布局)并终止于嵌套在根布局内的布局 - 这是布局路径中的布局 selected。布局路径通常表示为一个或多个MemoryLayout.PathElement 的序列PREVIEW 实例。
布局路径例如可用于在另一个布局内获取任意嵌套布局的offsets,快速获取与所选布局对应的内存访问句柄,或在另一个布局内获取任意嵌套布局的select。
这样的 layout paths 可以使用此类中的方法以编程方式构建。例如,给定如上构造的taggedValues布局实例,我们可以获得first序列元素中名为value的成员布局的偏移量,以位为单位,如下所示:
long valueOffset = taggedValues.bitOffset(PathElement.sequenceElement(0),
PathElement.groupElement("value")); // yields 32
value的成员布局,如下:
MemoryLayout value = taggedValues.select(PathElement.sequenceElement(),
PathElement.groupElement("value"));
MemoryLayout.PathElement.sequenceElement() 获得的)PREVIEW 方法)具有额外的自由维度,必须在运行时绑定。这在获得 内存段视图 var 句柄 时很重要PREVIEW 来自布局,如以下代码所示:
VarHandle valueHandle = taggedValues.varHandle(PathElement.sequenceElement(),
PathElement.groupElement("value"));
value的which成员布局应该从封闭序列布局中选择),因此var句柄valueHandle将具有additionallong访问坐标.
具有自由尺寸的布局路径也可用于创建偏移计算方法句柄,使用 bitOffset(PathElement...) 或 byteOffsetHandle(PathElement...) 方法。同样,自由维度被转换为创建的方法句柄的long参数。通过在调用方法句柄时提供这些索引,方法句柄可用于计算序列元素在不同索引处的偏移量。例如:
MethodHandle offsetHandle = taggedValues.byteOffsetHandle(PathElement.sequenceElement(),
PathElement.groupElement("kind"));
long offset1 = (long) offsetHandle.invokeExact(1L); // 8
long offset2 = (long) offsetHandle.invokeExact(2L); // 16
- 实现要求:
- 此接口的实现是不可变的、线程安全的和 value-based 。
- 密封类层次结构图:
- 自从:
- 19
-
内部类总结
内部类 -
方法总结
修饰符和类型方法描述long返回与此布局关联的对齐约束,以位表示。default longbitOffset(MemoryLayout.PathElementPREVIEW... elements) 计算给定布局路径选择的布局的偏移量(以位为单位),其中该路径被认为是此布局的根。default MethodHandlebitOffsetHandle(MemoryLayout.PathElementPREVIEW... elements) 创建一个方法句柄,可用于计算给定布局路径选择的布局的偏移量(以位为单位),其中该路径被视为植根于此布局。longbitSize()返回布局大小,以位为单位。default long返回与此布局关联的对齐约束,以字节表示。default longbyteOffset(MemoryLayout.PathElementPREVIEW... elements) 计算给定布局路径选择的布局的偏移量(以字节为单位),其中该路径被认为是此布局的根。default MethodHandlebyteOffsetHandle(MemoryLayout.PathElementPREVIEW... elements) 创建一个方法句柄,该句柄可用于计算给定布局路径选择的布局的偏移量(以字节为单位),其中该路径被视为植根于此布局。longbyteSize()返回布局大小,以字节为单位。boolean比较指定对象与此布局是否相等。inthashCode()返回此布局的哈希码值。name()返回与此布局关联的名称(如果有)。static PaddingLayoutPREVIEWpaddingLayout(long size) 创建具有给定大小的填充布局。default MemoryLayoutPREVIEWselect(MemoryLayout.PathElementPREVIEW... elements) 从以该布局为根的路径中选择布局。static SequenceLayoutPREVIEWsequenceLayout(long elementCount, MemoryLayoutPREVIEW elementLayout) 使用给定的元素布局和元素计数创建序列布局。static SequenceLayoutPREVIEWsequenceLayout(MemoryLayoutPREVIEW elementLayout) 使用给定的元素布局和最大元素数创建序列布局,使其不会溢出long。default MethodHandlesliceHandle(MemoryLayout.PathElementPREVIEW... elements) static StructLayoutPREVIEWstructLayout(MemoryLayoutPREVIEW... elements) 使用给定的成员布局创建结构布局。toString()返回此布局的字符串表示形式。static UnionLayoutPREVIEWunionLayout(MemoryLayoutPREVIEW... elements) 使用给定的成员布局创建联合布局。static ValueLayoutPREVIEWvalueLayout(Class<?> carrier, ByteOrder order) 创建给定 Java 载体和字节顺序的值布局。default VarHandlevarHandle(MemoryLayout.PathElementPREVIEW... elements) 创建一个 var 句柄,该句柄可用于访问给定布局路径选择的布局中的内存段,其中该路径被认为植根于此布局。withBitAlignment(long bitAlignment) 返回与此布局具有相同大小和名称但具有指定对齐约束(以位为单位)的相同类型的内存布局。返回与此布局具有相同大小和对齐约束但具有指定名称的相同类型的内存布局。
-
方法详情
-
bitSize
long bitSize()返回布局大小,以位为单位。- 返回:
- 布局大小,以位为单位
-
byteSize
long byteSize()返回布局大小,以字节为单位。- 返回:
- 布局大小,以字节为单位
- 抛出:
UnsupportedOperationException- 如果bitSize()不是 8 的倍数。
-
name
返回与此布局关联的名称(如果有)。- 返回:
- 与此布局关联的名称(如果有)
- 参见:
-
withName
返回与此布局具有相同大小和对齐约束但具有指定名称的相同类型的内存布局。- 参数:
name- 布局名称。- 返回:
- 具有给定名称的内存布局。
- 参见:
-
bitAlignment
long bitAlignment()返回与此布局关联的对齐约束,以位表示。布局对齐定义了 2 的幂A,这是布局的逐位对齐。如果A <= 8那么A/8是正确指向此布局的任何指针必须对齐的字节数。因此:A=8表示unaligned(通常意义上的),这在数据包中很常见。A=64表示字对齐(在 LP64 上),A=32int 对齐,A=16short 对齐等。A=512是 x86/SV ABI(对于 AVX-512 数据)要求的最严格对齐。
withBitAlignment(long)),则此方法返回与此布局关联的 自然排列 约束(以位为单位)。- 返回:
- 布局对齐约束,以位为单位。
-
byteAlignment
default long byteAlignment()返回与此布局关联的对齐约束,以字节表示。布局对齐定义了 2 的幂A,这是布局的字节对齐方式,其中A是正确指向此布局的任何指针必须对齐的字节数。因此:A=1表示unaligned(通常意义上的),这在数据包中很常见。A=8表示字对齐(在 LP64 上),A=4int 对齐,A=2short 对齐等。A=64是 x86/SV ABI(用于 AVX-512 数据)要求的最严格对齐。
withBitAlignment(long)),则此方法返回与此布局关联的 自然排列 约束(以字节为单位)。- 返回:
- 布局对齐约束,以字节为单位。
- 抛出:
UnsupportedOperationException- 如果bitAlignment()不是 8 的倍数。
-
withBitAlignment
返回与此布局具有相同大小和名称但具有指定对齐约束(以位为单位)的相同类型的内存布局。- 参数:
bitAlignment- 布局对齐约束,以位表示。- 返回:
- 具有给定对齐约束的内存布局。
- 抛出:
IllegalArgumentException- 如果bitAlignment不是 2 的幂,或者小于 8。
-
bitOffset
计算给定布局路径选择的布局的偏移量(以位为单位),其中该路径被认为是此布局的根。- 参数:
elements- 布局路径元素。- 返回:
elements中的布局路径选择的布局的偏移量(以位为单位)。- 抛出:
IllegalArgumentException- 如果布局路径没有选择嵌套在该布局中的任何布局,或者如果布局路径包含一个或多个选择多个序列元素索引的路径元素(参见MemoryLayout.PathElement.sequenceElement()PREVIEW 和MemoryLayout.PathElement.sequenceElement(long, long)PREVIEW ).NullPointerException- 如果elements == null,或者elements中的任何元素是null。
-
bitOffsetHandle
创建一个方法句柄,可用于计算给定布局路径选择的布局的偏移量(以位为单位),其中该路径被视为植根于此布局。返回的方法句柄的返回类型为
long,并且具有与提供的布局路径中的自由维度一样多的long参数类型(参见MemoryLayout.PathElement.sequenceElement()PREVIEW ), 其中参数的顺序对应于路径元素的顺序。返回的方法句柄可用于计算类似于bitOffset(PathElement...)的布局偏移量,但其中某些序列索引仅在调用方法句柄时指定。方法句柄返回的最终偏移量计算如下:
其中offset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)x_1、x_2、...x_n是作为long参数提供的 dynamic 值,而c_1、c_2、 ...c_m是 static 偏移常量和s_0,s_1, ...s_n是 static 步幅常数,它们源自布局路径.- 参数:
elements- 布局路径元素。- 返回:
- 一个方法句柄,可用于计算给定布局路径元素指定的布局元素的位偏移,当提供缺少的序列元素索引时。
- 抛出:
IllegalArgumentException- 如果布局路径包含一个或多个选择多个序列元素索引的路径元素(参见MemoryLayout.PathElement.sequenceElement(long, long)PREVIEW ).
-
byteOffset
计算给定布局路径选择的布局的偏移量(以字节为单位),其中该路径被认为是此布局的根。- 参数:
elements- 布局路径元素。- 返回:
elements中的布局路径选择的布局的偏移量(以字节为单位)。- 抛出:
IllegalArgumentException- 如果布局路径没有选择嵌套在该布局中的任何布局,或者如果布局路径包含一个或多个选择多个序列元素索引的路径元素(参见MemoryLayout.PathElement.sequenceElement()PREVIEW 和MemoryLayout.PathElement.sequenceElement(long, long)PREVIEW ).UnsupportedOperationException- 如果bitOffset(elements)不是 8 的倍数。NullPointerException- 如果elements == null,或者elements中的任何元素是null。
-
byteOffsetHandle
创建一个方法句柄,该句柄可用于计算给定布局路径选择的布局的偏移量(以字节为单位),其中该路径被视为植根于此布局。返回的方法句柄的返回类型为
long,并且具有与提供的布局路径中的自由维度一样多的long参数类型(参见MemoryLayout.PathElement.sequenceElement()PREVIEW ), 其中参数的顺序对应于路径元素的顺序。返回的方法句柄可用于计算类似于byteOffset(PathElement...)的布局偏移量,但其中一些序列索引仅在调用方法句柄时指定。方法句柄返回的最终偏移量计算如下:
其中bitOffset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n) offset = bitOffset / 8x_1、x_2、...x_n是作为long参数提供的 dynamic 值,而c_1、c_2、 ...c_m是 static 偏移常量和s_0,s_1, ...s_n是 static 步幅常数,它们源自布局路径.如果以位计算的偏移量不是 8 的倍数,则方法句柄将抛出
UnsupportedOperationException。- 参数:
elements- 布局路径元素。- 返回:
- 一个方法句柄,可用于计算给定布局路径元素指定的布局元素的字节偏移量,当提供缺少的序列元素索引时。
- 抛出:
IllegalArgumentException- 如果布局路径包含一个或多个选择多个序列元素索引的路径元素(参见MemoryLayout.PathElement.sequenceElement(long, long)PREVIEW ).
-
varHandle
创建一个 var 句柄,该句柄可用于访问给定布局路径选择的布局中的内存段,其中该路径被认为植根于此布局。返回的 var 句柄访问的最终地址可以计算如下:
其中address = base(segment) + offsetbase(segment)表示返回访问内存段物理基地址的函数。对于本机段,此函数仅返回本机段的 addressPREVIEW .对于堆段,这个函数更复杂,因为堆段的地址是虚拟化的。offset坐标可以用以下形式表示:
其中offset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)x_1、x_2、...x_n是作为long参数提供的 dynamic 值,而c_1、c_2、 ...c_m是 static 偏移常量和s_1,s_2, ...s_n是 static 步幅常数,它们源自布局路径.此外,提供的动态值必须符合从布局路径派生的某些边界,即
0 <= x_i < b_i,其中抛出1 <= i <= n或IndexOutOfBoundsException。- API 注意:
-
生成的 var 句柄将为该布局路径中包含的每个未指定的序列访问组件提供一个额外的
long访问坐标。此外,生成的 var 句柄具有某些 access mode restrictions ,这是所有内存段视图句柄共有的。 - 参数:
elements- 布局路径元素。- 返回:
-
一个 var 句柄,可用于访问由
elements中的布局路径选择的(可能嵌套的)布局中的内存段。 - 抛出:
UnsupportedOperationException- 如果布局路径中有一个或多个元素具有不兼容的对齐约束。IllegalArgumentException- 如果elements中的布局路径未选择值布局(请参见ValueLayoutPREVIEW ).- 参见:
-
sliceHandle
创建一个方法句柄,给定一个内存段,返回一个slicePREVIEW 对应于给定布局路径选择的布局,其中该路径被认为植根于此布局。返回的方法句柄的返回类型为
MemorySegment,以MemorySegment参数作为表示要切片的段的前导参数,并具有与提供的布局路径中的自由维度一样多的尾随long参数类型(参见MemoryLayout.PathElement.sequenceElement()PREVIEW ), 其中参数的顺序对应于路径元素的顺序。返回的方法句柄可用于创建类似于使用MemorySegment.asSlice(long, long)的切片PREVIEW ,但是偏移量参数是根据调用方法句柄时指定的索引动态计算的。返回段的偏移量计算如下:
其中bitOffset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n) offset = bitOffset / 8x_1、x_2、...x_n是作为long参数提供的 dynamic 值,而c_1、c_2、 ...c_m是 static 偏移常量和s_1,s_2, ...s_n是 static 步幅常数,它们源自布局路径.计算偏移量后,返回的段就好像通过调用创建:
其中segment.asSlice(offset, layout.byteSize());segment是要切片的段,其中layout是由给定布局路径选择的布局,根据select(PathElement...)。如果以位计算的偏移量不是 8 的倍数,则方法句柄将抛出
UnsupportedOperationException。- 参数:
elements- 布局路径元素。- 返回:
- 一个方法句柄,可用于在给定段的情况下创建所选布局元素的切片。
- 抛出:
UnsupportedOperationException- 如果所选布局的大小(以位为单位)不是 8 的倍数。
-
select
从以该布局为根的路径中选择布局。- 参数:
elements- 布局路径元素。- 返回:
-
由
elements中的布局路径选择的布局。 - 抛出:
IllegalArgumentException- 如果布局路径没有选择嵌套在该布局中的任何布局,或者如果布局路径包含一个或多个选择一个或多个序列元素索引的路径元素(参见MemoryLayout.PathElement.sequenceElement(long)PREVIEW 和MemoryLayout.PathElement.sequenceElement(long, long)PREVIEW ).
-
equals
比较指定对象与此布局是否相等。返回true当且仅当指定的对象也是一个布局,并且它等于这个布局。如果两个布局属于同一类型,具有相同的大小、名称和对齐约束,则它们被认为是相等的。此外,根据布局类型,还必须满足其他条件:- 如果两个值布局具有相同的order,则它们被认为是相等的PREVIEW 和 carrierPREVIEW
- 如果两个序列布局具有相同的元素计数,则它们被认为是相等的(参见
SequenceLayout.elementCount()PREVIEW ),以及它们的元素布局(参见SequenceLayout.elementLayout()PREVIEW ) 也相等 - 如果两组布局属于同一类型,则它们被认为是相等的(参见
StructLayoutPREVIEW ,UnionLayoutPREVIEW ) 以及它们的成员布局(参见GroupLayout.memberLayouts()PREVIEW ) 也相等
-
hashCode
int hashCode()返回此布局的哈希码值。 -
toString
String toString()返回此布局的字符串表示形式。 -
paddingLayout
创建具有给定大小的填充布局。- 参数:
size- 以位为单位的填充大小。- 返回:
- 新的选择器布局。
- 抛出:
IllegalArgumentException- 如果size <= 0。
-
valueLayout
创建给定 Java 载体和字节顺序的值布局。结果值布局的类型由提供的载体决定:ValueLayout.OfBooleanPREVIEW , 对于boolean.classValueLayout.OfBytePREVIEW , 对于byte.classValueLayout.OfShortPREVIEW , 对于short.classValueLayout.OfCharPREVIEW , 对于char.classValueLayout.OfIntPREVIEW , 对于int.classValueLayout.OfFloatPREVIEW , 对于float.classValueLayout.OfLongPREVIEW , 对于long.classValueLayout.OfDoublePREVIEW , 对于double.classValueLayout.OfAddressPREVIEW , 对于MemorySegment.class
- 参数:
carrier- 值布局载体。order- 值布局的字节顺序。- 返回:
- 具有给定 Java 载体和字节顺序的值布局。
- 抛出:
IllegalArgumentException- 如果运营商类型不受支持。
-
sequenceLayout
使用给定的元素布局和元素计数创建序列布局。- 参数:
elementCount- 序列元素计数。elementLayout- 序列元素布局。- 返回:
- 具有给定元素布局和大小的新序列布局。
- 抛出:
IllegalArgumentException- 如果elementCount为负。
-
sequenceLayout
使用给定的元素布局和最大元素数创建序列布局,使其不会溢出long。这等效于以下代码:sequenceLayout(Long.MAX_VALUE / elementLayout.bitSize(), elementLayout);- 参数:
elementLayout- 序列元素布局。- 返回:
- 具有给定元素布局和最大元素数的新序列布局。
-
structLayout
使用给定的成员布局创建结构布局。- 参数:
elements- 结构布局的成员布局。- 返回:
- 具有给定成员布局的结构布局。
- 抛出:
IllegalArgumentException- 如果成员布局的 位大小 总和溢出。
-
unionLayout
使用给定的成员布局创建联合布局。- 参数:
elements- 联合布局的成员布局。- 返回:
- 具有给定成员布局的联合布局。
-
MemoryLayout。