MemorySegment 是 Java 平台的预览 API。
有两种内存段:
- heap segment 由 Java 堆内的内存区域(“堆上”区域)支持并提供对内存区域的访问。
- native segment 由 Java 堆外的内存区域(“堆外”区域)支持并提供访问权限。
ofArray(int[]) 工厂方法之一来获取堆段。这些方法返回由保存指定 Java 数组的堆上区域支持的内存段。
本机段可以通过调用 allocateNative(long, long, SegmentScope) 工厂方法之一获得,该方法返回一个内存段,该内存段由新分配的堆外区域支持,具有给定的大小并与给定的对齐约束对齐。或者,可以通过 mapping 获得原生片段PREVIEW 将文件放入新的堆外区域(在某些系统中,此操作有时称为 mmap )。通过这种方式获得的段称为mapped段,其内容可以与底层内存映射文件坚持和加载来往。
两种段都使用相同的方法读取和写入,称为 访问操作 。对内存段的访问操作始终且仅提供对获得该段的区域的访问。
内存段的特点
每个内存段都有一个 address ,表示为long 值。段地址的性质取决于段的类型:
- 堆段的地址不是物理地址,而是支持该段的内存区域内的偏移量。该区域位于 Java 堆内部,因此随着时间的推移,垃圾收集可能会导致该区域在物理内存中重新定位,但这不会暴露给
MemorySegmentAPI 的客户端,他们会看到该区域支持的堆段的稳定 virtualized 地址。从ofArray(int[])工厂方法之一获得的堆段的地址为零。 - 本机段(包括映射段)的地址表示支持该段的内存区域的物理地址。
每个内存段都有一个 size 。堆段的大小是从获取它的 Java 数组派生的。此大小在 Java 运行时中是可预测的。本机段的大小要么显式传递(如在 allocateNative(long, SegmentScope) 中),要么从 MemoryLayout 派生PREVIEW (如 allocateNative(MemoryLayout, SegmentScope) )。内存段的大小通常是正数,但也可能是 zero,但绝不是负数。
内存段的地址和大小共同确保对该段的访问操作不能超出outside支持该段的内存区域的边界。也就是说,内存段有 spatial bounds 。
每个内存段都与一个scope相关联PREVIEW .这确保了当支持内存段的内存区域不再可用时(例如,在与访问的内存段关联的范围不再是 活 之后),不会发生对内存段的访问操作PREVIEW ).也就是说,内存段有 temporal bounds 。
最后,内存段上的访问操作受相关作用域强制执行的线程限制检查的约束;也就是说,如果段与 全球范围 关联PREVIEW 或者一个自动范围PREVIEW ,它可以被多个线程访问。如果段与竞技场范围相关联,则只能使用 竞技场限制特征 兼容地访问它。
访问内存段
可以使用此类中提供的各种访问操作读取或写入内存段(例如get(ValueLayout.OfInt, long) )。每个访问操作都需要一个值布局PREVIEW ,指定值的大小和形状,以及以字节表示的偏移量。例如,要使用 默认字节顺序 从段中读取一个 int,可以使用以下代码:
MemorySegment segment = ...
int value = segment.get(ValueLayout.JAVA_INT, 0);
MemorySegment segment = ...
int value = segment.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0);
long 偏移量。使用 MethodHandles 类中定义的 var 句柄组合器函数调整段 var 句柄视图可以获得更复杂的 var 句柄:
MemorySegment segment = ...
VarHandle intHandle = MethodHandles.memorySegmentViewVarHandle(ValueLayout.JAVA_INT);
MethodHandle multiplyExact = MethodHandles.lookup()
.findStatic(Math.class, "multiplyExact",
MethodType.methodType(long.class, long.class, long.class));
intHandle = MethodHandles.filterCoordinates(intHandle, 1,
MethodHandles.insertArguments(multiplyExact, 0, 4L));
intHandle.get(segment, 3L); // get int element at offset 3 * 4 = 12
MemorySegment segment = ...
VarHandle intHandle = ValueLayout.JAVA_INT.arrayElementVarHandle();
intHandle.get(segment, 3L); // get int element at offset 3 * 4 = 12
切片内存段
内存段支持 切片 。对内存段进行切片会返回一个新的内存段,该内存段由与原始内存相同的内存区域支持。切片段的地址是通过添加偏移量(以字节表示)从原始段的地址派生的。切片段的大小可以隐式导出(通过从原始段的大小中减去指定的偏移量),也可以显式提供。换句话说,切片段比原始段有 stricter 个空间边界:Arena arena = ...
MemorySegment segment = arena.allocate(100);
MemorySegment slice = segment.asSlice(50, 10);
slice.get(ValueLayout.JAVA_INT, 20); // Out of bounds!
arena.close();
slice.get(ValueLayout.JAVA_INT, 0); // Already closed!
segment 的偏移量 50 开始、长度为 10 字节的切片。即,slice 的地址为 segment.address() + 50,其大小为 10。因此,尝试读取 slice 段偏移量 20 处的 int 值将导致异常。 时间界限PREVIEW 原始段的部分由其切片继承;也就是说,当与 segment 关联的范围不再是 活PREVIEW slice 也将变得不可访问。
客户端可能会从一个段中获得一个 Stream ,然后可以使用它对该段进行切片(根据给定的元素布局),甚至允许多个线程在不相交的段切片上并行工作(为此,该段必须是与允许 使用权 的范围关联PREVIEW 来自多个线程)。以下代码可用于并行地对内存段中的所有 int 值求和:
try (Arena arena = Arena.openShared()) {
SequenceLayout SEQUENCE_LAYOUT = MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_INT);
MemorySegment segment = arena.allocate(SEQUENCE_LAYOUT);
int sum = segment.elements(ValueLayout.JAVA_INT).parallel()
.mapToInt(s -> s.get(ValueLayout.JAVA_INT, 0))
.sum();
}
Alignment
内存段上的访问操作不仅受到段的空间和时间边界的限制,而且还受到指定给操作的值布局的alignment constraint 的限制。访问操作只能访问段中表示物理内存中地址的那些偏移量,根据布局,这些偏移量为 aligned。如果地址是布局对齐约束的整数倍,则物理内存中的地址根据布局为 aligned。例如地址1000按照8字节对齐约束对齐(因为1000是8的整数倍),按照4字节对齐约束,按照2字节对齐约束;相比之下,地址 1004 根据 4 字节对齐约束和 2 字节对齐约束而不是 8 字节对齐约束对齐。访问操作需要遵守对齐,因为它会影响访问操作的性能,并且还可以确定在给定的物理地址上哪些访问操作可用。例如,使用VarHandle 的 原子访问操作 操作仅允许在对齐地址处使用。此外,无论被访问的段是本机段还是堆段,对齐都适用于访问操作。
如果被访问的segment是native segment,那么它在物理内存中的address可以结合偏移量得到物理内存中的target address。下面的伪函数演示了这一点:
boolean isAligned(MemorySegment segment, long offset, MemoryLayout layout) {
return ((segment.address() + offset) % layout.byteAlignment()) == 0;
}
- 在 8 字节对齐约束下,可以在偏移量 0、8、16、24 等处访问地址为 1000 的本机段,因为目标地址(1000、1008、1016、1024)是 8 字节对齐的。不允许访问偏移量 1-7 或 9-15 或 17-23,因为目标地址不是 8 字节对齐的。
- 在 4 字节对齐约束下,可以在偏移量 0、4、8、12 等处访问地址为 1000 的本机段,因为目标地址(1000、1004、1008、1012)是 4 字节对齐的。不允许访问偏移量 1-3 或 5-7 或 9-11,因为目标地址不是 4 字节对齐的。
- 在 2 字节对齐约束下,可以在偏移量 0、2、4、6 等处访问地址为 1000 的本机段,因为目标地址(1000、1002、1004、1006)是 2 字节对齐的。不允许访问偏移量 1 或 3 或 5,因为目标地址不是 2 字节对齐的。
- 可以在 4 字节对齐约束下在偏移量 0、4、8、12 等处以及在 2 字节对齐约束下在偏移量 0、2、4、6 等处访问地址为 1004 的本机段。在 8 字节对齐约束下,可以在偏移量 4、12、20、28 等处访问它。
- 在 2 字节对齐约束下,可以在偏移量 0、2、4、6 等处访问地址为 1006 的本机段。在 4 字节对齐约束下,它可以在偏移量 2、6、10、14 等处访问。在 8 字节对齐约束下,它可以在偏移量 2、10、18、26 等处访问。
- 在 1 字节对齐约束下,可以在偏移量 0、1、2、3 等处访问地址为 1007 的本机段。在 2 字节对齐约束下,它可以在偏移量 1、3、5、7 等处访问。在 4 字节对齐约束下,它可以在偏移量 1、5、9、13 等处访问。在一个8字节对齐约束,可以在偏移量1、9、17、25等处访问。
用于访问段的对齐约束通常由存储在段中的数据结构的形状决定。例如,如果程序员希望在本机段中存储一系列 8 字节值,则应通过 allocateNative(long, long, SegmentScope) 或 allocateNative(MemoryLayout, SegmentScope) 指定 8 字节对齐约束来分配该段。这些工厂确保支持返回段的堆外内存区域具有 8 字节对齐的起始地址。随后,程序员可以在感兴趣的偏移量(0、8、16、24 等)处访问段,因为知道每个此类访问都是对齐的。
如果被访问的段是堆段,那么判断访问是否对齐就比较复杂。该段在物理内存中的地址是未知的,甚至不是固定的(在垃圾回收期间重定位该段时它可能会改变)。这意味着该地址不能与指定的偏移量组合来确定物理内存中的目标地址。由于对齐约束always指的是物理内存中地址的对齐,因此原则上无法确定堆段中的任何偏移量是否对齐。例如,假设程序员选择 8 字节对齐约束并尝试访问堆段中的偏移量 16。如果堆段的地址 0 对应物理地址 1000,则目标地址 (1016) 将对齐,但如果地址 0 对应物理地址 1004,则目标地址 (1020) 不会对齐。允许访问根据程序员选择的对齐约束对齐但在物理内存中可能无法预测对齐(例如,由于平台考虑和/或垃圾收集行为)的目标地址是不可取的。
实际上,Java 运行时在内存中布置数组,以便每个 n 字节元素出现在 n 字节对齐的物理地址上。即使在垃圾回收期间重新定位数组,运行时也会保留此不变性。访问操作依赖于这个不变量来确定堆段中的指定偏移量是否引用物理内存中的对齐地址。例如:
long[]数组的起始物理地址将是 8 字节对齐的(例如 1000),因此连续的长元素出现在 8 字节对齐的地址(例如 1000、1008、1016、1024 等)。在 8 字节对齐约束下,可以在偏移量 0、8、16、24 等处访问long[]数组。此外,在 4 字节对齐约束下,可以在偏移量 0、4、8、12 等处访问该段,因为目标地址(1000、1004、1008、1012)是 4 字节对齐的。并且,在 2 字节对齐约束下,可以在偏移量 0、2、4、6 等处访问该段,因为目标地址(例如 1000、1002、1004、1006)是 2 字节对齐的。short[]数组的起始物理地址将是 2 字节对齐的(例如 1006),以便连续的短元素出现在 2 字节对齐的地址(例如 1006、1008、1010、1012 等)。在 2 字节对齐约束下,可以在偏移量 0、2、4、6 等处访问由short[]数组支持的堆段。在 4 字节对齐约束下,无法在 any 偏移处访问该段,因为无法保证目标地址将是 4 字节对齐的,例如,偏移量 0 将对应于物理地址 1006,而偏移量 1 将对应于物理地址1007. 类似地,在 8 字节对齐约束下,不能在任何偏移处访问该段,因为无法保证目标地址将是 8 字节对齐的,例如,偏移量 2 对应物理地址 1008,但偏移量 4将对应于物理地址 1010。
换句话说,堆段具有 maximum 对齐方式,它源自支持该段的 Java 数组元素的大小,如下表所示:
堆段只能使用其对齐方式小于或等于与堆段关联的最大对齐方式的布局来访问。尝试使用对齐方式大于与堆段关联的最大对齐方式的布局访问堆段将失败,如以下示例所示:
阵列类型(支持区域) 支持的最大对齐(以字节为单位) boolean[]1byte[]1char[]2short[]2int[]4float[]4long[]8double[]8
MemorySegment byteSegment = MemorySegment.ofArray(new byte[10]);
byteSegment.get(ValueLayout.JAVA_INT, 0); // fails: layout alignment is 4, segment max alignment is 1
long[] )支持的堆段,能够支持更大的最大对齐:
MemorySegment longSegment = MemorySegment.ofArray(new long[10]);
longSegment.get(ValueLayout.JAVA_INT, 0); // ok: layout alignment is 4, segment max alignment is 8
ValueLayout.JAVA_INT_UNALIGNED PREVIEW ) 将它们的对齐约束设置为 1:
MemorySegment byteSegment = MemorySegment.ofArray(new byte[10]);
byteSegment.get(ValueLayout.JAVA_INT_UNALIGNED, 0); // ok: layout alignment is 1, segment max alignment is 1
零长度内存段
当与 外部函数 交互时,这些函数通常分配内存区域并返回指向该区域的指针。使用内存段对内存区域建模具有挑战性,因为 Java 运行时无法洞察该区域的大小。只有存储在指针中的区域起始地址可用。例如,返回类型为char* 的 C 函数可能返回指向包含单个 char 值的区域的指针,或指向包含 char 值数组的区域的指针,其中数组的大小可能在单独的参数中提供。对于调用外部函数并希望使用其结果的代码而言,数组的大小并不明显。
Linker PREVIEW 表示从具有 zero-length memory segment 的外部函数返回的指针。段的地址就是指针中存放的地址。该段的大小为零。同样,当客户端从内存段读取 address 时,将返回一个零长度的内存段。
由于零长度段具有微不足道的空间边界,因此任何访问这些段的尝试都将失败并返回 IndexOutOfBoundsException 。这是一项至关重要的安全功能:由于这些段与大小未知的内存区域相关联,因此无法验证涉及这些段的任何访问操作。实际上,一个零长度的内存段 wraps 一个地址,如果没有明确的意图就不能使用它。
与外部函数交互时获得的零长度内存段与global scope 相关联PREVIEW .这是因为 Java 运行时除了无法了解支持从外部函数返回的指针的内存区域的大小之外,也无法了解分配它的外部函数为所述内存区域指定的生命周期.全局范围确保获得的段可以不透明地传递给其他接受指针的外部函数。
要访问本机零长度内存段,客户端有两个选项,都是 unsafe 。客户端可以 获得 new 原生段,具有新的空间和时间边界,如下所示:
SegmentScope scope = ... // obtains a scope
MemorySegment foreign = someSegment.get(ValueLayout.ADDRESS, 0); // wrap address into segment (size = 0)
MemorySegment segment = MemorySegment.ofAddress(foreign.address(), 4, scope); // create new segment (size = 4)
int x = segment.get(ValueLayout.JAVA_INT, 0); //ok
MemorySegment foreign = someSegment.get(ValueLayout.ADDRESS.asUnbounded(), 0); // wrap address into segment (size = Long.MAX_VALUE)
int x = foreign.get(ValueLayout.JAVA_INT, 0); //ok
ofAddress(long, long, SegmentScope) 和 ValueLayout.OfAddress.asUnbounded() PREVIEW 是 restricted 方法,应谨慎使用:例如,不正确地调整段大小可能会导致 VM 在尝试访问内存段时崩溃。
采用哪种方法在很大程度上取决于客户端在获取包装本机指针的内存段时可用的信息。例如,如果此类指针指向 C 结构,则客户端可能更愿意不安全地调整段的大小,以匹配结构的大小(以便 API 检测到越界访问)。然而,在其他情况下,将没有或几乎没有关于什么空间和/或时间边界应该与给定本地指针相关联的信息。在这些情况下,使用无界地址布局可能更可取。
- 实现要求:
- 此接口的实现是不可变的、线程安全的和 value-based 。
- 自从:
- 19
-
字段摘要
字段 -
方法总结
修饰符和类型方法描述longaddress()返回此内存段的地址。static MemorySegmentPREVIEWallocateNative(long byteSize, long byteAlignment, SegmentScopePREVIEW scope) 创建具有给定大小(以字节为单位)、对齐方式(以字节为单位)和范围的本机段。static MemorySegmentPREVIEWallocateNative(long byteSize, SegmentScopePREVIEW scope) 创建具有给定大小(以字节为单位)和范围的本机段。static MemorySegmentPREVIEWallocateNative(MemoryLayoutPREVIEW layout, SegmentScopePREVIEW scope) 创建具有给定布局和范围的本机段。array()返回与此内存段关联的 Java 数组(如果有)。将此段包装在ByteBuffer中。返回此片段的一部分,该片段是此片段与提供的片段之间的重叠部分。返回此段的只读视图。default MemorySegmentPREVIEWasSlice(long offset) 在给定的偏移量处返回此内存段的一片。asSlice(long offset, long newSize) 在给定的偏移量处返回此内存段的一片。longbyteSize()返回此内存段的大小(以字节为单位)。static voidcopy(MemorySegmentPREVIEW srcSegment, long srcOffset, MemorySegmentPREVIEW dstSegment, long dstOffset, long bytes) 执行从源段到目标段的批量复制。static voidcopy(MemorySegmentPREVIEW srcSegment, ValueLayoutPREVIEW srcElementLayout, long srcOffset, MemorySegmentPREVIEW dstSegment, ValueLayoutPREVIEW dstElementLayout, long dstOffset, long elementCount) 执行从源段到目标段的批量复制。static voidcopy(MemorySegmentPREVIEW srcSegment, ValueLayoutPREVIEW srcLayout, long srcOffset, Object dstArray, int dstIndex, int elementCount) 将多个元素从源内存段复制到目标数组。static voidcopy(Object srcArray, int srcIndex, MemorySegmentPREVIEW dstSegment, ValueLayoutPREVIEW dstLayout, long dstOffset, int elementCount) 将多个元素从源数组复制到目标内存段。default MemorySegmentPREVIEW执行从给定源段到此段的批量复制。elements(MemoryLayoutPREVIEW elementLayout) 返回此段中不相交切片(其大小与指定布局的大小匹配)的顺序Stream。boolean比较指定对象与此内存段是否相等。fill(byte value) 将值填充到此内存段中。voidforce()强制将对此map段的内容所做的任何更改写入映射段的文件描述符所描述的存储设备。default MemorySegmentPREVIEWget(ValueLayout.OfAddressPREVIEW layout, long offset) 以给定的偏移量和给定的布局从该段中读取一个地址。default booleanget(ValueLayout.OfBooleanPREVIEW layout, long offset) 使用给定布局从给定偏移量处的该段读取boolean。default byteget(ValueLayout.OfBytePREVIEW layout, long offset) 使用给定布局从给定偏移量处的该段中读取一个字节。default charget(ValueLayout.OfCharPREVIEW layout, long offset) 以给定的偏移量和给定的布局从该段中读取一个字符。default doubleget(ValueLayout.OfDoublePREVIEW layout, long offset) 使用给定布局从给定偏移量处的该段读取双精度值。default floatget(ValueLayout.OfFloatPREVIEW layout, long offset) 使用给定布局从给定偏移量处的该段读取一个浮点数。default intget(ValueLayout.OfIntPREVIEW layout, long offset) 使用给定布局从给定偏移量处的该段读取一个 int。default longget(ValueLayout.OfLongPREVIEW layout, long offset) 使用给定的布局在给定的偏移量处从该段读取一个 long。default shortget(ValueLayout.OfShortPREVIEW layout, long offset) 使用给定的布局,在给定的偏移量处从该段读取一个短片。default MemorySegmentPREVIEWgetAtIndex(ValueLayout.OfAddressPREVIEW layout, long index) 从给定索引处的给定段读取地址,按给定布局大小缩放。default chargetAtIndex(ValueLayout.OfCharPREVIEW layout, long index) 从给定索引处的该段中读取一个字符,按给定布局大小缩放。default doublegetAtIndex(ValueLayout.OfDoublePREVIEW layout, long index) 从给定索引处的该段读取双精度值,按给定布局大小缩放。default floatgetAtIndex(ValueLayout.OfFloatPREVIEW layout, long index) 从给定索引处的该段读取浮点数,按给定布局大小缩放。default intgetAtIndex(ValueLayout.OfIntPREVIEW layout, long index) 从给定索引处的该段读取一个 int,按给定布局大小缩放。default longgetAtIndex(ValueLayout.OfLongPREVIEW layout, long index) 从给定索引处的该段读取 long,按给定布局大小缩放。default shortgetAtIndex(ValueLayout.OfShortPREVIEW layout, long index) 从给定索引处的该段读取一个短片,按给定布局大小缩放。default StringgetUtf8String(long offset) 从此段中给定偏移处读取 UTF-8 编码、以 null 结尾的字符串。inthashCode()返回此内存段的哈希码值。booleanisLoaded()确定此map段的内容是否驻留在物理内存中。booleanisMapped()如果此段是映射段,则返回true。booleanisNative()如果此段是本机段,则返回true。boolean如果此段是只读的,则返回true。voidload()将此map段的内容加载到物理内存中。default longmismatch(MemorySegmentPREVIEW other) 查找并返回此段与给定其他段之间第一个不匹配的偏移量(以字节为单位)。static longmismatch(MemorySegmentPREVIEW srcSegment, long srcFromOffset, long srcToOffset, MemorySegmentPREVIEW dstSegment, long dstFromOffset, long dstToOffset) 查找并返回源段和目标段之间第一个不匹配的相对偏移量(以字节为单位)。static MemorySegmentPREVIEWofAddress(long address) 从给定的 地址值 创建一个零长度的本机段。static MemorySegmentPREVIEWofAddress(long address, long byteSize) 创建具有给定大小和 地址值 的本机段。static MemorySegmentPREVIEWofAddress(long address, long byteSize, SegmentScopePREVIEW scope) 创建具有给定大小、地址和范围的本机段。static MemorySegmentPREVIEWofAddress(long address, long byteSize, SegmentScopePREVIEW scope, Runnable cleanupAction) 创建具有给定大小、地址和范围的本机段。static MemorySegmentPREVIEWofArray(byte[] byteArray) 创建由保存给定字节数组的堆上内存区域支持的堆段。static MemorySegmentPREVIEWofArray(char[] charArray) 创建一个由保存给定 char 数组的堆上内存区域支持的堆段。static MemorySegmentPREVIEWofArray(double[] doubleArray) 创建由保存给定双精度数组的堆上内存区域支持的堆段。static MemorySegmentPREVIEWofArray(float[] floatArray) 创建一个由保存给定浮点数组的堆上内存区域支持的堆段。static MemorySegmentPREVIEWofArray(int[] intArray) 创建由保存给定 int 数组的堆上内存区域支持的堆段。static MemorySegmentPREVIEWofArray(long[] longArray) 创建一个由保存给定长数组的堆上内存区域支持的堆段。static MemorySegmentPREVIEWofArray(short[] shortArray) 创建一个由保存给定短数组的堆上内存区域支持的堆段。static MemorySegmentPREVIEW创建一个内存段,该内存段由支持给定Buffer实例的同一内存区域支持。scope()返回与此内存段关联的范围。long返回提供的段相对于此段的偏移量(以字节为单位)。default voidset(ValueLayout.OfAddressPREVIEW layout, long offset, MemorySegmentPREVIEW value) 使用给定的布局在给定的偏移量处将地址写入此段。default voidset(ValueLayout.OfBooleanPREVIEW layout, long offset, boolean value) 使用给定的布局在给定的偏移量处将boolean写入该段。default voidset(ValueLayout.OfBytePREVIEW layout, long offset, byte value) 使用给定的布局在给定的偏移量处将一个字节写入该段。default voidset(ValueLayout.OfCharPREVIEW layout, long offset, char value) 使用给定的布局在给定的偏移量处将 char 写入该段。default voidset(ValueLayout.OfDoublePREVIEW layout, long offset, double value) 使用给定的布局在给定的偏移量处将双精度值写入此段。default voidset(ValueLayout.OfFloatPREVIEW layout, long offset, float value) 使用给定的布局在给定的偏移量处将浮点数写入该段。default voidset(ValueLayout.OfIntPREVIEW layout, long offset, int value) 使用给定的布局在给定的偏移量处将一个 int 写入该段。default voidset(ValueLayout.OfLongPREVIEW layout, long offset, long value) 使用给定的布局在给定的偏移量处将 long 写入该段。default voidset(ValueLayout.OfShortPREVIEW layout, long offset, short value) 使用给定的布局,在给定的偏移量处将一个 short 写入该段。default voidsetAtIndex(ValueLayout.OfAddressPREVIEW layout, long index, MemorySegmentPREVIEW value) 在给定索引处将地址写入此段,按给定布局大小缩放。default voidsetAtIndex(ValueLayout.OfCharPREVIEW layout, long index, char value) 在给定索引处将 char 写入此段,按给定布局大小缩放。default voidsetAtIndex(ValueLayout.OfDoublePREVIEW layout, long index, double value) 在给定索引处将双精度值写入此段,按给定布局大小缩放。default voidsetAtIndex(ValueLayout.OfFloatPREVIEW layout, long index, float value) 在给定索引处将浮点数写入此段,按给定布局大小缩放。default voidsetAtIndex(ValueLayout.OfIntPREVIEW layout, long index, int value) 在给定的索引处将一个 int 写入此段,按给定的布局大小缩放。default voidsetAtIndex(ValueLayout.OfLongPREVIEW layout, long index, long value) 在给定索引处将 long 写入此段,按给定布局大小缩放。default voidsetAtIndex(ValueLayout.OfShortPREVIEW layout, long index, short value) 在给定的索引处写入一个 short 到该段,按给定的布局大小缩放。default voidsetUtf8String(long offset, String str) 以给定的偏移量将给定的字符串写入此段,使用 UTF-8 编码将其转换为以 null 结尾的字节序列。spliterator(MemoryLayoutPREVIEW elementLayout) 返回此内存段的拆分器。byte[]toArray(ValueLayout.OfBytePREVIEW elementLayout) 将此内存段的内容复制到一个新的字节数组中。char[]toArray(ValueLayout.OfCharPREVIEW elementLayout) 将此内存段的内容复制到一个新的 char 数组中。double[]toArray(ValueLayout.OfDoublePREVIEW elementLayout) 将此内存段的内容复制到一个新的双精度数组中。float[]toArray(ValueLayout.OfFloatPREVIEW elementLayout) 将此内存段的内容复制到一个新的 float 数组中。int[]toArray(ValueLayout.OfIntPREVIEW elementLayout) 将此内存段的内容复制到一个新的 int 数组中。long[]toArray(ValueLayout.OfLongPREVIEW elementLayout) 将此内存段的内容复制到一个新的长数组中。short[]toArray(ValueLayout.OfShortPREVIEW elementLayout) 将此内存段的内容复制到一个新的短数组中。voidunload()从物理内存中卸载此map段的内容。
-
字段详细信息
-
NULL
对NULL地址建模的零长度本机段。
-
-
方法详情
-
address
long address()返回此内存段的地址。- 返回:
- 该内存段的地址
-
array
返回与此内存段关联的 Java 数组(如果有)。- 返回:
- 与此内存段关联的 Java 数组(如果有)
-
spliterator
返回此内存段的拆分器。返回的拆分器报告Spliterator.SIZED、Spliterator.SUBSIZED、Spliterator.IMMUTABLE、Spliterator.NONNULL和Spliterator.ORDERED特征。返回的 spliterator 根据指定的元素布局拆分此段;也就是说,如果提供的布局大小为 N,则调用
Spliterator.trySplit()将导致拆分器服务大约S/N个元素(取决于 N 是否为偶数),其中S是该段的大小。因此,只要S/N >= 2就可以拆分。拆分器返回与该段关联的范围相同的段。返回的 spliterator 有效地允许将该段分割成不相交的 切片 ,然后可以由多个线程并行处理。
- 参数:
elementLayout- 用于拆分的布局。- 返回:
- 该段的元素拆分器
- 抛出:
IllegalArgumentException- 如果elementLayout大小为零,或者以elementLayout大小为模的段大小大于零,如果该段在提供的布局中为 与对齐约束不兼容,或者elementLayout对齐方式大于其大小。
-
elements
返回此段中不相交切片(其大小与指定布局的大小匹配)的顺序Stream。调用这个方法相当于下面的代码:StreamSupport.stream(segment.spliterator(elementLayout), false);- 参数:
elementLayout- 用于拆分的布局。- 返回:
-
在此段中的不相交切片上的顺序
Stream。 - 抛出:
IllegalArgumentException- 如果elementLayout大小为零,或者以elementLayout大小为模的段大小大于零,如果该段在提供的布局中为 与对齐约束不兼容,或者elementLayout对齐方式大于其大小。
-
scope
SegmentScope PREVIEW scope()返回与此内存段关联的范围。- 返回:
- 与此内存段关联的范围
-
byteSize
long byteSize()返回此内存段的大小(以字节为单位)。- 返回:
- 此内存段的大小(以字节为单位)
-
asSlice
在给定的偏移量处返回此内存段的一片。返回的段地址是该段的地址加上给定的偏移量;它的大小由给定的参数指定。- 参数:
offset- 新的段基址偏移量(相对于该段的地址),以字节为单位指定。newSize- 新的段大小,以字节为单位指定。- 返回:
- 此内存段的一部分。
- 抛出:
IndexOutOfBoundsException- 如果offset < 0、offset > byteSize()、newSize < 0或newSize > byteSize() - offset- 参见:
-
asSlice
在给定的偏移量处返回此内存段的一片。返回的段地址是该段的地址加上给定的偏移量;它的大小是通过从此段大小中减去指定的偏移量来计算的。相当于下面的代码:
asSlice(offset, byteSize() - offset);- 参数:
offset- 新的段基址偏移量(相对于该段的地址),以字节为单位指定。- 返回:
- 此内存段的一部分。
- 抛出:
IndexOutOfBoundsException- 如果是offset < 0或offset > byteSize()。- 参见:
-
isReadOnly
boolean isReadOnly()如果此段是只读的,则返回true。- 返回:
true,如果该段是只读的- 参见:
-
asReadOnly
MemorySegment PREVIEW asReadOnly()返回此段的只读视图。生成的段将与该段相同,但尝试覆盖返回段的内容将导致运行时异常。- 返回:
- 该段的只读视图
- 参见:
-
isNative
boolean isNative()- 返回:
true如果此段是本机段。
-
isMapped
boolean isMapped()如果此段是映射段,则返回true。创建map内存段,例如使用FileChannel.map(FileChannel.MapMode, long, long, SegmentScope)PREVIEW 工厂,或 包装 a 映射字节缓冲区。- 返回:
true如果此段是映射段。
-
asOverlappingSlice
返回此片段的一部分,该片段是此片段与提供的片段之间的重叠部分。如果可以找到至少两个由同一内存区域支持的切片
L1(来自S1)和L2(来自S2),则称两个段S1和S2重叠。因此,本国的 段不可能与堆段重叠;在这种情况下,或者当没有发生重叠时,返回null。- 参数:
other- 测试与该段重叠的段。- 返回:
- 该段的一部分(发生重叠的地方)。
-
segmentOffset
返回提供的段相对于此段的偏移量(以字节为单位)。偏移量是相对于该段地址的,可以是负值也可以是正值。例如,如果两个段都是本机段,或由同一数组支持的堆段,则可以按如下方式计算结果偏移量:
如果段共享相同的地址,则返回other.address() - segment.address()0。如果other是该段的一个切片,则偏移量始终为0 <= x < this.byteSize()。- 参数:
other- 要检索偏移量的段。- 返回:
- 提供的段的相对偏移量(以字节为单位)。
- 抛出:
UnsupportedOperationException- 如果两个段无法比较,例如因为它们属于不同类型,或者因为它们由不同的 Java 数组支持。
-
fill
将值填充到此内存段中。更具体地说,将给定值填充到该段的每个地址中。等效于(但可能比)以下代码:
不考虑或保证正在设置的特定内存元素的顺序。byteHandle = MemoryLayout.ofSequence(ValueLayout.JAVA_BYTE) .varHandle(byte.class, MemoryLayout.PathElement.sequenceElement()); for (long l = 0; l < segment.byteSize(); l++) { byteHandle.set(segment.address(), l, value); }填充可用于初始化或重置段的内存。
- 参数:
value- 填充到该段中的值- 返回:
- 这个内存段
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。UnsupportedOperationException- 如果此段是只读的(请参阅isReadOnly())。
-
copyFrom
执行从给定源段到此段的批量复制。更具体地说,源段中偏移量为0到src.byteSize() - 1的字节被复制到偏移量为0到src.byteSize() - 1的该段中。调用这个方法相当于下面的代码:
MemorySegment.copy(src, 0, this, 0, src.byteSize);- 参数:
src- 源段。- 返回:
- 这个片段。
- 抛出:
IndexOutOfBoundsException- 如果src.byteSize() > this.byteSize()。IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalStateException- 如果与src关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则src.scope().isAccessibleBy(T) == false。UnsupportedOperationException- 如果此段是只读的(请参阅isReadOnly())。
-
mismatch
查找并返回此段与给定其他段之间第一个不匹配的偏移量(以字节为单位)。偏移量是相对于每个段的 address 的,并且将在 0(含)到较小内存段(不包括)的 size(以字节为单位)的范围内。如果这两个段共享一个公共前缀,则返回的偏移量是公共前缀的长度,因此这两个段在各自段内的该偏移量处存在不匹配。如果一个段是另一个段的正确前缀,则返回的偏移量是段大小中最小的,因此偏移量仅对较大的段有效。否则,不存在不匹配并返回
-1。- 参数:
other- 要测试与该段不匹配的段- 返回:
- 此段与给定的其他段之间第一个不匹配的相对偏移量(以字节为单位),如果不匹配则为 -1
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalStateException- 如果与other关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则other.scope().isAccessibleBy(T) == false。
-
isLoaded
boolean isLoaded()确定此map段的内容是否驻留在物理内存中。true的返回值意味着很可能该段中的所有数据都驻留在物理内存中,因此可以在不引起任何虚拟内存页面错误或 I/O 操作的情况下进行访问。false的返回值并不一定意味着该段的内容不驻留在物理内存中。返回值是一个提示,而不是保证,因为在调用此方法返回时,底层操作系统可能已经调出该段的某些数据。
- 返回:
true如果这个段的内容很可能驻留在物理内存中- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。UnsupportedOperationException- 如果该段不是映射内存段,例如isMapped() == false。
-
load
void load()将此map段的内容加载到物理内存中。此方法尽最大努力确保在返回时此段的此内容驻留在物理内存中。调用此方法可能会导致发生一些页面错误和 I/O 操作。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。UnsupportedOperationException- 如果该段不是映射内存段,例如isMapped() == false。
-
unload
void unload()从物理内存中卸载此map段的内容。此方法尽最大努力确保此段的内容不再驻留在物理内存中。在调用此方法后访问此段的内容可能会导致发生一些页面错误和 I/O 操作(因为此段的内容可能需要调回页面)。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。UnsupportedOperationException- 如果该段不是映射内存段,例如isMapped() == false。
-
force
void force()强制将对此map段的内容所做的任何更改写入映射段的文件描述符所描述的存储设备。如果与此map段关联的文件描述符驻留在本地存储设备上,则当此方法返回时,可以保证自创建此段或自上次调用此方法以来对此段所做的所有更改都已写入该设备.
如果与此map段关联的文件描述符不驻留在本地设备上,则无法做出此类保证。
如果此段未映射到读/写模式 (
FileChannel.MapMode.READ_WRITE),则调用此方法可能无效。特别是,该方法对以只读或私有映射模式映射的段没有影响。此方法可能会或可能不会影响特定于实现的映射模式。- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。UnsupportedOperationException- 如果该段不是映射内存段,例如isMapped() == false。UncheckedIOException- 如果将此段的内容写入关联的存储设备时出现 I/O 错误
-
asByteBuffer
ByteBuffer asByteBuffer()将此段包装在ByteBuffer中。返回缓冲区的某些属性链接到该段的属性。例如,如果该段是 immutable(例如该段是只读段,请参阅isReadOnly()),则生成的缓冲区是 read-only(请参阅Buffer.isReadOnly())。此外,如果这是本机段,则生成的缓冲区为 direct(请参阅ByteBuffer.isDirect())。返回缓冲区的位置(参见
Buffer.position())最初设置为零,而返回缓冲区的容量和限制(分别参见Buffer.capacity()和Buffer.limit())设置为该段的大小(参见byteSize())。因此,如果此段的大小大于Integer.MAX_VALUE,则无法返回字节缓冲区。返回缓冲区的生命周期将与该段的生命周期相关联。也就是说,在与该段关联的范围不再是活之后访问返回的缓冲区PREVIEW 会抛出一个
IllegalStateException。同样,从线程T访问返回的缓冲区,这样scope().isAccessible(T) == false将抛出WrongThreadException。如果此段与只能从单个线程访问的范围相关联,则对生成的缓冲区调用读/写 I/O 操作可能会导致抛出未指定的异常。此类有问题的操作的示例是
AsynchronousSocketChannel.read(ByteBuffer)和AsynchronousSocketChannel.write(ByteBuffer)。最后,生成的缓冲区的字节顺序是
ByteOrder.BIG_ENDIAN;这可以使用ByteBuffer.order(java.nio.ByteOrder)更改。- 返回:
-
此内存段的
ByteBuffer视图。 - 抛出:
UnsupportedOperationException- 如果此段无法映射到ByteBuffer实例,例如,因为它模拟了一个不基于byte[]的基于堆的段,或者如果它的大小大于Integer.MAX_VALUE。
-
toArray
将此内存段的内容复制到一个新的字节数组中。- 参数:
elementLayout- 源元素布局。如果与布局关联的字节顺序与 原生顺序 不同,则将对每个数组元素执行字节交换操作。- 返回:
- 一个新的字节数组,其内容是从此内存段复制的。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalStateException- 如果该段的内容无法复制到byte[]实例中,例如它的大小大于Integer.MAX_VALUE。
-
toArray
将此内存段的内容复制到一个新的短数组中。- 参数:
elementLayout- 源元素布局。如果与布局关联的字节顺序与 原生顺序 不同,则将对每个数组元素执行字节交换操作。- 返回:
- 一个新的短数组,其内容是从此内存段复制的。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalStateException- 如果此段的内容无法复制到short[]实例中,例如因为byteSize() % 2 != 0或byteSize() / 2 > Integer#MAX_VALUE
-
toArray
将此内存段的内容复制到一个新的 char 数组中。- 参数:
elementLayout- 源元素布局。如果与布局关联的字节顺序与 原生顺序 不同,则将对每个数组元素执行字节交换操作。- 返回:
- 一个新的 char 数组,其内容是从此内存段复制的。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalStateException- 如果此段的内容无法复制到char[]实例中,例如因为byteSize() % 2 != 0或byteSize() / 2 > Integer#MAX_VALUE。
-
toArray
将此内存段的内容复制到一个新的 int 数组中。- 参数:
elementLayout- 源元素布局。如果与布局关联的字节顺序与 原生顺序 不同,则将对每个数组元素执行字节交换操作。- 返回:
- 一个新的 int 数组,其内容是从此内存段复制的。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalStateException- 如果此段的内容无法复制到int[]实例中,例如因为byteSize() % 4 != 0或byteSize() / 4 > Integer#MAX_VALUE。
-
toArray
将此内存段的内容复制到一个新的 float 数组中。- 参数:
elementLayout- 源元素布局。如果与布局关联的字节顺序与 原生顺序 不同,则将对每个数组元素执行字节交换操作。- 返回:
- 一个新的 float 数组,其内容是从此内存段复制的。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalStateException- 如果此段的内容无法复制到float[]实例中,例如因为byteSize() % 4 != 0或byteSize() / 4 > Integer#MAX_VALUE。
-
toArray
将此内存段的内容复制到一个新的长数组中。- 参数:
elementLayout- 源元素布局。如果与布局关联的字节顺序与 原生顺序 不同,则将对每个数组元素执行字节交换操作。- 返回:
- 一个新的 long 数组,其内容是从此内存段复制的。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalStateException- 如果此段的内容无法复制到long[]实例中,例如因为byteSize() % 8 != 0或byteSize() / 8 > Integer#MAX_VALUE。
-
toArray
将此内存段的内容复制到一个新的双精度数组中。- 参数:
elementLayout- 源元素布局。如果与布局关联的字节顺序与 原生顺序 不同,则将对每个数组元素执行字节交换操作。- 返回:
- 一个新的双精度数组,其内容是从此内存段复制的。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalStateException- 如果此段的内容无法复制到double[]实例中,例如因为byteSize() % 8 != 0或byteSize() / 8 > Integer#MAX_VALUE。
-
getUtf8String
从此段中给定偏移处读取 UTF-8 编码、以 null 结尾的字符串。此方法始终用此字符集的默认替换字符串替换格式错误的输入和不可映射的字符序列。当需要对解码过程进行更多控制时,应使用
CharsetDecoder类。- 参数:
offset- 将发生此访问操作的字节偏移量(相对于此段地址)。- 返回:
-
一个 Java 字符串,由从给定起始地址读取的字节构成,直到(但不包括)第一个
'\0'终止符(假设找到一个)。 - 抛出:
IllegalArgumentException- 如果 UTF-8 字符串的大小大于平台支持的最大字符串。IndexOutOfBoundsException- 如果是offset < 0或S + offset > byteSize(),其中S是 UTF-8 字符串的大小(包括终止符)。IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。
-
setUtf8String
以给定的偏移量将给定的字符串写入此段,使用 UTF-8 编码将其转换为以 null 结尾的字节序列。此方法始终用此字符集的默认替换字符串替换格式错误的输入和不可映射的字符序列。当需要对解码过程进行更多控制时,应使用
CharsetDecoder类。如果给定的字符串包含任何
'\0'个字符,它们也将被复制。这意味着,根据用于读取字符串的方法(例如getUtf8String(long)),再次读取时字符串将被截断。- 参数:
offset- 将发生此访问操作的字节偏移量(相对于此段地址)。这个写操作的最终地址可以表示为address() + offset。str- 要写入此段的 Java 字符串。- 抛出:
IndexOutOfBoundsException- 如果是offset < 0或str.getBytes().length() + offset >= byteSize()。IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。
-
ofBuffer
创建一个内存段,该内存段由支持给定Buffer实例的同一内存区域支持。该段相对于缓冲区的位置(包括)开始,并相对于缓冲区的限制(不包括)结束。如果缓冲区是 只读 ,则生成的段也将是 只读 。此外,如果缓冲区是 直接缓冲区 ,则返回的段是本机段;否则返回的内存段是堆段。
与返回的段关联的范围
S计算如下:- 如果通过在范围为
S'的内存段上调用asByteBuffer()获得缓冲区,则S = S';或者 - 如果缓冲区是堆缓冲区,则
S是 全球范围PREVIEW ;或者 - 如果缓冲区是直接缓冲区,则
S是始终处于活动状态并保持缓冲区可访问的作用域。因此,只要返回的段可到达,支持缓冲区实例的堆外内存区域将保持可用。
- 参数:
buffer- 要变成新内存段的缓冲区实例。- 返回:
- 从给定的缓冲区实例派生的内存段。
- 抛出:
IllegalArgumentException- 如果提供的buffer是堆缓冲区但不受数组支持。例如,通过 (CharBuffer.wrap(CharSequence)或CharBuffer.wrap(char[], int, int)直接或间接获得的缓冲区不受数组支持。
- 如果通过在范围为
-
ofArray
- 参数:
byteArray- 支持堆内存段的原始数组。- 返回:
- 由字节数组支持的堆内存段。
-
ofArray
- 参数:
charArray- 支持堆段的原始数组。- 返回:
- 由 char 数组支持的堆内存段。
-
ofArray
- 参数:
shortArray- 支持堆段的原始数组。- 返回:
- 由短数组支持的堆内存段。
-
ofArray
- 参数:
intArray- 支持堆段的原始数组。- 返回:
- 由 int 数组支持的堆内存段。
-
ofArray
- 参数:
floatArray- 支持堆段的原始数组。- 返回:
- 由浮点数组支持的堆内存段。
-
ofArray
- 参数:
longArray- 支持堆段的原始数组。- 返回:
- 由长数组支持的堆内存段。
-
ofArray
- 参数:
doubleArray- 支持堆段的原始数组。- 返回:
- 由双数组支持的堆内存段。
-
ofAddress
- 参数:
address- 返回的本机段的地址。- 返回:
- 具有给定地址的零长度本机段。
-
ofAddress
创建具有给定大小和 地址值 的本机段。返回的段与 全球范围 相关联PREVIEW .这等效于以下代码:
这个方法是restricted 。受限方法是不安全的,如果使用不当,它们的使用可能会使 JVM 崩溃,或者更糟的是,无声地导致内存损坏。因此,客户应避免依赖受限的方法,并尽可能使用安全和受支持的功能。ofAddress(address, byteSize, SegmentScope.global());- 参数:
address- 返回的本机段的地址。byteSize- 返回的本机段的大小(以字节为单位)。- 返回:
- 具有给定地址和大小的零长度本机段。
- 抛出:
IllegalArgumentException- 如果byteSize < 0。IllegalCallerException- 如果调用者所在的模块未启用本机访问。
-
ofAddress
创建具有给定大小、地址和范围的本机段。当与自定义内存源(例如自定义分配器)交互时,此方法很有用,其中一些底层内存区域的地址通常是从外部代码获得的(通常作为普通的long值)。返回的段不是只读的(参见
isReadOnly()),并且与提供的范围相关联。这等效于以下代码:
这个方法是restricted 。受限方法是不安全的,如果使用不当,它们的使用可能会使 JVM 崩溃,或者更糟的是,无声地导致内存损坏。因此,客户应避免依赖受限的方法,并尽可能使用安全和受支持的功能。ofAddress(address, byteSize, scope, null);- 参数:
address- 返回的段地址。byteSize- 所需的大小。scope- 与返回的本机段关联的范围。- 返回:
- 具有给定地址、大小和范围的本机段。
- 抛出:
IllegalArgumentException- 如果byteSize < 0。IllegalStateException- 如果scope不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope.isAccessibleBy(T) == false。IllegalCallerException- 如果调用者所在的模块未启用本机访问。
-
ofAddress
static MemorySegment PREVIEW ofAddress(long address, long byteSize, SegmentScope PREVIEW scope, Runnable cleanupAction) 创建具有给定大小、地址和范围的本机段。当与自定义内存源(例如自定义分配器)交互时,此方法很有用,其中一些底层内存区域的地址通常是从外部代码获得的(通常作为普通的long值)。返回的段不是只读的(参见
isReadOnly()),并且与提供的范围相关联。当作用域变为 not 活 时,将调用提供的清理操作(如果有)PREVIEW .
客户端应确保地址和边界指向一个有效的内存区域,该区域可用于读取和写入(如果适用);尝试从 Java 代码访问无效地址将返回任意值,没有可见效果,或者导致抛出未指定的异常。
这个方法是restricted 。受限方法是不安全的,如果使用不当,它们的使用可能会使 JVM 崩溃,或者更糟的是,无声地导致内存损坏。因此,客户应避免依赖受限的方法,并尽可能使用安全和受支持的功能。
- 参数:
address- 返回的段地址。byteSize- 所需的大小。scope- 与返回的本机段关联的范围。cleanupAction- 要与返回的段关联的自定义清理操作(可以为 null)。- 返回:
- 具有给定地址、大小和范围的本机段。
- 抛出:
IllegalArgumentException- 如果byteSize < 0。IllegalStateException- 如果scope不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope.isAccessibleBy(T) == false。IllegalCallerException- 如果调用者所在的模块未启用本机访问。
-
allocateNative
static MemorySegment PREVIEW allocateNative(MemoryLayout PREVIEW layout, SegmentScope PREVIEW scope) 创建具有给定布局和范围的本机段。与返回的本机段关联的生存期堆外内存区域由提供的范围确定。当作用域变为 not 活 时,释放堆外内存区域PREVIEW .如果使用
Arena获得范围PREVIEW ,客户端负责确保在返回的段不再使用时关闭竞技场,否则将导致堆外内存泄漏。作为替代方案,自动范围PREVIEW 可以使用,允许与返回的本机段关联的堆外内存区域在不再引用范围后的某个未指定时间自动释放。返回的内存段的 address 是支持该段的新分配的堆外区域的起始地址。此外,返回段的 address 将根据提供的布局的对齐约束进行对齐。
这等效于以下代码:
allocateNative(layout.bytesSize(), layout.bytesAlignment(), scope);支持返回的本机段的堆外区域初始化为零。
- 参数:
layout- 支持本机段的堆外内存区域的布局。scope- 与返回的本机段关联的范围。- 返回:
- 一个新的原生细分市场。
- 抛出:
IllegalStateException- 如果scope不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope.isAccessibleBy(T) == false。
-
allocateNative
创建具有给定大小(以字节为单位)和范围的本机段。与返回的本机段关联的生存期堆外内存区域由提供的范围确定。当作用域变为 not 活 时,释放堆外内存区域PREVIEW .如果使用
Arena获得范围PREVIEW ,客户端负责确保在返回的段不再使用时关闭竞技场,否则将导致堆外内存泄漏。作为替代方案,自动范围PREVIEW 可以使用,允许与返回的本机段关联的堆外内存区域在不再引用范围后的某个未指定时间自动释放。返回的内存段的 address 是支持该段的新分配的堆外区域的起始地址。此外,返回段的 address 保证至少为 1 字节对齐。
这等效于以下代码:
allocateNative(bytesSize, 1, scope);支持返回的本机段的堆外区域初始化为零。
- 参数:
byteSize- 支持本机内存段的堆外内存区域的大小(以字节为单位)。scope- 与返回的本机段关联的范围。- 返回:
- 一个新的本机内存段。
- 抛出:
IllegalArgumentException- 如果byteSize < 0。IllegalStateException- 如果scope不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope.isAccessibleBy(T) == false。
-
allocateNative
static MemorySegment PREVIEW allocateNative(long byteSize, long byteAlignment, SegmentScope PREVIEW scope) 创建具有给定大小(以字节为单位)、对齐方式(以字节为单位)和范围的本机段。与返回的本机段关联的生存期堆外内存区域由提供的范围确定。当作用域变为 not 活 时,释放堆外内存区域PREVIEW .如果使用
Arena获得范围PREVIEW ,客户端负责确保在返回的段不再使用时关闭竞技场,否则将导致堆外内存泄漏。作为替代方案,自动范围PREVIEW 可以使用,允许与返回的本机段关联的堆外内存区域在不再引用范围后的某个未指定时间自动释放。返回的内存段的 address 是支持该段的新分配的堆外区域的起始地址。此外,返回段的 address 将根据提供的对齐约束进行对齐。
支持返回的本机段的堆外区域初始化为零。
- 参数:
byteSize- 支持本机内存段的堆外内存区域的大小(以字节为单位)。byteAlignment- 支持本机内存段的堆外内存区域的对齐约束(以字节为单位)。scope- 与返回的本机段关联的范围。- 返回:
- 一个新的本机内存段。
- 抛出:
IllegalArgumentException- 如果byteSize < 0、byteAlignment <= 0或byteAlignment不是 2 的幂。IllegalStateException- 如果scope不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope.isAccessibleBy(T) == false。
-
copy
static void copy(MemorySegment PREVIEW srcSegment, long srcOffset, MemorySegment PREVIEW dstSegment, long dstOffset, long bytes) 执行从源段到目标段的批量复制。更具体地说,源段中偏移量为srcOffset到srcOffset + bytes - 1的字节被复制到偏移量为dstOffset到dstOffset + bytes - 1的目标段中。如果源段与这个段重叠,那么复制就好像源段中偏移量
srcOffset到srcOffset + bytes - 1的字节首先被复制到一个大小为bytes的临时段,然后临时段的内容被复制到偏移量为dstOffset到dstOffset + bytes - 1的目标段。如果在不常见的情况下,源段和目标段不重叠,但指的是使用不同地址的相同后备存储的重叠区域,则批量复制的结果是不确定的。例如,如果同一文件被 映射 分为两个段,则可能会发生这种情况。
调用这个方法相当于下面的代码:
MemorySegment.copy(srcSegment, ValueLayout.JAVA_BYTE, srcOffset, dstSegment, ValueLayout.JAVA_BYTE, dstOffset, bytes);- 参数:
srcSegment- 源代码段。srcOffset- 源段的起始偏移量(以字节为单位)。dstSegment- 目标段。dstOffset- 目标段的起始偏移量(以字节为单位)。bytes- 要复制的字节数。- 抛出:
IllegalStateException- 如果与srcSegment关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则srcSegment.scope().isAccessibleBy(T) == false。IllegalStateException- 如果与dstSegment关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则dstSegment.scope().isAccessibleBy(T) == false。IndexOutOfBoundsException- 如果srcOffset + bytes > srcSegment.byteSize()或如果dstOffset + bytes > dstSegment.byteSize(),或者如果srcOffset、dstOffset或bytes是< 0。UnsupportedOperationException- 如果目标段是只读的(请参阅isReadOnly())。
-
copy
static void copy(MemorySegment PREVIEW srcSegment, ValueLayout PREVIEW srcElementLayout, long srcOffset, MemorySegment PREVIEW dstSegment, ValueLayout PREVIEW dstElementLayout, long dstOffset, long elementCount) 执行从源段到目标段的批量复制。更具体地说,如果S是元素布局的字节大小,则将源段中偏移量为srcOffset到srcOffset + (elementCount * S) - 1的字节复制到偏移量为dstOffset到dstOffset + (elementCount * S) - 1的目标段中。复制以元素方式进行:源段中的字节被解释为布局为
srcElementLayout的元素序列,而目标段中的字节被解释为布局为dstElementLayout的元素序列。两个元素布局必须具有相同的大小S。如果两个元素布局的字节顺序不同,则在复制操作期间相应地交换对应于每个要复制的元素的字节。如果源段与这个段重叠,那么复制就好像源段中偏移量
srcOffset到srcOffset + (elementCount * S) - 1处的字节首先被复制到一个大小为bytes的临时段,然后临时段的内容被复制到偏移量为dstOffset到dstOffset + (elementCount * S) - 1的目标段。如果在不常见的情况下,源段和目标段不重叠,但指的是使用不同地址的相同后备存储的重叠区域,则批量复制的结果是不确定的。例如,如果同一文件被 映射 分为两个段,则可能会发生这种情况。
- 参数:
srcSegment- 源代码段。srcElementLayout- 与源句段关联的元素布局。srcOffset- 源段的起始偏移量(以字节为单位)。dstSegment- 目标段。dstElementLayout- 与目标段关联的元素布局。dstOffset- 目标段的起始偏移量(以字节为单位)。elementCount- 要复制的元素数。- 抛出:
IllegalArgumentException- 如果元素布局具有不同的大小,如果源(或目标)段/偏移量在源(或目标)元素布局中为 与对齐约束不兼容,或者如果源(或目标)元素布局对齐大于其尺寸。IllegalStateException- 如果与srcSegment关联的 scope 不是 活PREVIEW .WrongThreadException- 如果此方法是从线程T调用的,则srcSegment().scope().isAccessibleBy(T) == false。IllegalStateException- 如果与dstSegment关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则dstSegment().scope().isAccessibleBy(T) == false。IndexOutOfBoundsException- 如果srcOffset + (elementCount * S) > srcSegment.byteSize()或dstOffset + (elementCount * S) > dstSegment.byteSize(),其中S是元素布局的字节大小,或者如果srcOffset、dstOffset或elementCount是< 0。UnsupportedOperationException- 如果目标段是只读的(请参阅isReadOnly())。
-
get
使用给定布局从给定偏移量处的该段中读取一个字节。- 参数:
layout- 要读取的内存区域的布局。offset- 将发生此访问操作的字节偏移量(相对于此段地址)。- 返回:
- 从该段读取的字节值。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。
-
set
使用给定的布局在给定的偏移量处将一个字节写入该段。- 参数:
layout- 要写入的内存区域的布局。offset- 将发生此访问操作的字节偏移量(相对于此段地址)。value- 要写入的字节值。- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。UnsupportedOperationException- 如果此段是 只读 。
-
get
使用给定布局从给定偏移量处的该段读取boolean。- 参数:
layout- 要读取的内存区域的布局。offset- 将发生此访问操作的字节偏移量(相对于此段地址)。- 返回:
- 从该段读取的boolean。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。
-
set
使用给定的布局在给定的偏移量处将boolean写入该段。- 参数:
layout- 要写入的内存区域的布局。offset- 将发生此访问操作的字节偏移量(相对于此段地址)。value- 要写入的boolean。- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。UnsupportedOperationException- 如果此段是 只读 。
-
get
以给定的偏移量和给定的布局从该段中读取一个字符。- 参数:
layout- 要读取的内存区域的布局。offset- 将发生此访问操作的字节偏移量(相对于此段地址)。- 返回:
- 从该段读取的 char 值。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。
-
set
使用给定的布局在给定的偏移量处将 char 写入该段。- 参数:
layout- 要写入的内存区域的布局。offset- 将发生此访问操作的字节偏移量(相对于此段地址)。value- 要写入的 char 值。- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。UnsupportedOperationException- 如果此段是 只读 。
-
get
使用给定的布局,在给定的偏移量处从该段读取一个短片。- 参数:
layout- 要读取的内存区域的布局。offset- 将发生此访问操作的字节偏移量(相对于此段地址)。- 返回:
- 从该段读取的短值。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。
-
set
使用给定的布局,在给定的偏移量处将一个 short 写入该段。- 参数:
layout- 要写入的内存区域的布局。offset- 将发生此访问操作的字节偏移量(相对于此段地址)。value- 要写入的短值。- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。UnsupportedOperationException- 如果此段是 只读 。
-
get
使用给定布局从给定偏移量处的该段读取一个 int。- 参数:
layout- 要读取的内存区域的布局。offset- 将发生此访问操作的字节偏移量(相对于此段地址)。- 返回:
- 从该段读取的 int 值。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。
-
set
使用给定的布局在给定的偏移量处将一个 int 写入该段。- 参数:
layout- 要写入的内存区域的布局。offset- 将发生此访问操作的字节偏移量(相对于此段地址)。value- 要写入的 int 值。- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。UnsupportedOperationException- 如果此段是 只读 。
-
get
使用给定布局从给定偏移量处的该段读取一个浮点数。- 参数:
layout- 要读取的内存区域的布局。offset- 将发生此访问操作的字节偏移量(相对于此段地址)。- 返回:
- 从该段读取的浮点值。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。
-
set
使用给定的布局在给定的偏移量处将浮点数写入该段。- 参数:
layout- 要写入的内存区域的布局。offset- 将发生此访问操作的字节偏移量(相对于此段地址)。value- 要写入的浮点值。- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。UnsupportedOperationException- 如果此段是 只读 。
-
get
使用给定的布局在给定的偏移量处从该段读取一个 long。- 参数:
layout- 要读取的内存区域的布局。offset- 将发生此访问操作的字节偏移量(相对于此段地址)。- 返回:
- 从该段读取的长值。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。
-
set
使用给定的布局在给定的偏移量处将 long 写入该段。- 参数:
layout- 要写入的内存区域的布局。offset- 将发生此访问操作的字节偏移量(相对于此段地址)。value- 要写入的 long 值。- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。UnsupportedOperationException- 如果此段是 只读 。
-
get
使用给定布局从给定偏移量处的该段读取双精度值。- 参数:
layout- 要读取的内存区域的布局。offset- 将发生此访问操作的字节偏移量(相对于此段地址)。- 返回:
- 从该段读取的双精度值。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。
-
set
使用给定的布局在给定的偏移量处将双精度值写入此段。- 参数:
layout- 要写入的内存区域的布局。offset- 将发生此访问操作的字节偏移量(相对于此段地址)。value- 要写入的双精度值。- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。UnsupportedOperationException- 如果此段是 只读 。
-
get
以给定的偏移量和给定的布局从该段中读取一个地址。读取地址包装在与 全球范围 关联的本机段中PREVIEW .在正常情况下,返回段的大小为0。但是,如果提供的布局是 无界PREVIEW 地址布局,则返回段的大小为Long.MAX_VALUE。- 参数:
layout- 要读取的内存区域的布局。offset- 将发生此访问操作的字节偏移量(相对于此段地址)。- 返回:
- 包装从该段读取的地址的本机段。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。
-
set
使用给定的布局在给定的偏移量处将地址写入此段。- 参数:
layout- 要写入的内存区域的布局。offset- 将发生此访问操作的字节偏移量(相对于此段地址)。value- 要写入的地址值。- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。UnsupportedOperationException- 如果此段是 只读 。UnsupportedOperationException- 如果value不是 本国的 段。
-
getAtIndex
从给定索引处的该段中读取一个字符,按给定布局大小缩放。- 参数:
layout- 要读取的内存区域的布局。index- 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为(index * layout.byteSize())。- 返回:
- 从该段读取的 char 值。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。
-
setAtIndex
在给定索引处将 char 写入此段,按给定布局大小缩放。- 参数:
layout- 要写入的内存区域的布局。index- 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为(index * layout.byteSize())。value- 要写入的 char 值。- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。UnsupportedOperationException- 如果此段是 只读 。
-
getAtIndex
从给定索引处的该段读取一个短片,按给定布局大小缩放。- 参数:
layout- 要读取的内存区域的布局。index- 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为(index * layout.byteSize())。- 返回:
- 从该段读取的短值。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。
-
setAtIndex
在给定的索引处写入一个 short 到该段,按给定的布局大小缩放。- 参数:
layout- 要写入的内存区域的布局。index- 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为(index * layout.byteSize())。value- 要写入的短值。- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。UnsupportedOperationException- 如果此段是 只读 。
-
getAtIndex
从给定索引处的该段读取一个 int,按给定布局大小缩放。- 参数:
layout- 要读取的内存区域的布局。index- 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为(index * layout.byteSize())。- 返回:
- 从该段读取的 int 值。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。
-
setAtIndex
在给定的索引处将一个 int 写入此段,按给定的布局大小缩放。- 参数:
layout- 要写入的内存区域的布局。index- 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为(index * layout.byteSize())。value- 要写入的 int 值。- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。UnsupportedOperationException- 如果此段是 只读 。
-
getAtIndex
从给定索引处的该段读取浮点数,按给定布局大小缩放。- 参数:
layout- 要读取的内存区域的布局。index- 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为(index * layout.byteSize())。- 返回:
- 从该段读取的浮点值。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。
-
setAtIndex
在给定索引处将浮点数写入此段,按给定布局大小缩放。- 参数:
layout- 要写入的内存区域的布局。index- 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为(index * layout.byteSize())。value- 要写入的浮点值。- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。UnsupportedOperationException- 如果此段是 只读 。
-
getAtIndex
从给定索引处的该段读取 long,按给定布局大小缩放。- 参数:
layout- 要读取的内存区域的布局。index- 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为(index * layout.byteSize())。- 返回:
- 从该段读取的长值。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。
-
setAtIndex
在给定索引处将 long 写入此段,按给定布局大小缩放。- 参数:
layout- 要写入的内存区域的布局。index- 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为(index * layout.byteSize())。value- 要写入的 long 值。- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。UnsupportedOperationException- 如果此段是 只读 。
-
getAtIndex
从给定索引处的该段读取双精度值,按给定布局大小缩放。- 参数:
layout- 要读取的内存区域的布局。index- 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为(index * layout.byteSize())。- 返回:
- 从该段读取的双精度值。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。
-
setAtIndex
在给定索引处将双精度值写入此段,按给定布局大小缩放。- 参数:
layout- 要写入的内存区域的布局。index- 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为(index * layout.byteSize())。value- 要写入的双精度值。- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。UnsupportedOperationException- 如果此段是 只读 。
-
getAtIndex
从给定索引处的给定段读取地址,按给定布局大小缩放。读取地址包装在与 全球范围 关联的本机段中PREVIEW .在正常情况下,返回段的大小为0。但是,如果提供的布局是 无界PREVIEW 地址布局,则返回段的大小为Long.MAX_VALUE。- 参数:
layout- 要读取的内存区域的布局。index- 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为(index * layout.byteSize())。- 返回:
- 包装从该段读取的地址的本机段。
- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。
-
setAtIndex
default void setAtIndex(ValueLayout.OfAddress PREVIEW layout, long index, MemorySegment PREVIEW value) 在给定索引处将地址写入此段,按给定布局大小缩放。- 参数:
layout- 要写入的内存区域的布局。index- 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为(index * layout.byteSize())。value- 要写入的地址值。- 抛出:
IllegalStateException- 如果与该段关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则scope().isAccessibleBy(T) == false。IllegalArgumentException- 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。IndexOutOfBoundsException- 当访问操作落在内存段的 spatial bounds 之外时。UnsupportedOperationException- 如果此段是 只读 。UnsupportedOperationException- 如果value不是 本国的 段。
-
equals
比较指定对象与此内存段是否相等。返回true当且仅当指定的对象也是一个内存段,并且如果两个段引用相同的位置,在某个内存区域。更具体地说,对于被视为相等的两个段s1和s2,以下所有条件都必须为真:s1.array().equals(s2.array()),即两个段必须是同一类;两者都是 原生片段 ,由堆外内存支持,或者两者都由相同的堆上 Java 数组支持;s1.address() == s2.address(),即两个段的地址应该相同。这意味着这两个段要么引用某个堆外区域中的相同位置,要么引用其关联的 Java 数组实例中的相同位置。
- 重写:
equals在类Object中- API 注意:
-
该方法不对两个内存段的内容进行结构比较。客户端可以改用
mismatch(MemorySegment)方法在结构上比较内存段。请注意,此方法确实not比较两个片段的时间和空间边界。因此,它适合执行地址检查,例如检查本机段是否具有NULL地址。 - 参数:
that- 要与此内存段进行相等比较的对象。- 返回:
true如果指定的对象等于这个内存段。- 参见:
-
hashCode
int hashCode()返回此内存段的哈希码值。 -
copy
static void copy(MemorySegment PREVIEW srcSegment, ValueLayout PREVIEW srcLayout, long srcOffset, Object dstArray, int dstIndex, int elementCount) 将多个元素从源内存段复制到目标数组。其大小和对齐约束由给定布局指定的元素从源段中读取,从给定偏移量(以字节表示)开始,并在给定索引处复制到目标数组中。支持的数组类型是byte[]、char[]、short[]、int[]、float[]、long[]和double[]。- 参数:
srcSegment- 源代码段。srcLayout- 源元素布局。如果与布局关联的字节顺序与 原生顺序 不同,则将对每个数组元素执行字节交换操作。srcOffset- 源段的起始偏移量(以字节为单位)。dstArray- 目标数组。dstIndex- 目标数组的起始索引。elementCount- 要复制的数组元素的数量。- 抛出:
IllegalStateException- 如果与srcSegment关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则srcSegment().isAccessibleBy(T) == false。IllegalArgumentException- 如果dstArray不是数组,或者它是数组但其类型不受支持,如果目标数组组件类型与源元素布局的载体不匹配,如果源段/偏移量在源中为 与对齐约束不兼容元素布局,或者如果目标元素布局对齐方式大于其大小。
-
copy
static void copy(Object srcArray, int srcIndex, MemorySegment PREVIEW dstSegment, ValueLayout PREVIEW dstLayout, long dstOffset, int elementCount) 将多个元素从源数组复制到目标内存段。其大小和对齐约束由给定布局指定的元素从源数组中读取,从给定索引开始,并以给定偏移量(以字节表示)复制到目标段中。支持的数组类型是byte[]、char[]、short[]、int[]、float[]、long[]和double[]。- 参数:
srcArray- 源数组。srcIndex- 源数组的起始索引。dstSegment- 目标段。dstLayout- 目标元素布局。如果与布局关联的字节顺序与 原生顺序 不同,则将对每个数组元素执行字节交换操作。dstOffset- 目标段的起始偏移量(以字节为单位)。elementCount- 要复制的数组元素的数量。- 抛出:
IllegalStateException- 如果与dstSegment关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则dstSegment().isAccessibleBy(T) == false。IllegalArgumentException- 如果srcArray不是数组,或者它是一个数组但其类型不受支持,如果源数组组件类型与目标元素布局的载体不匹配,如果目标段/偏移量在目标中为 与对齐约束不兼容元素布局,或者如果目标元素布局对齐方式大于其大小。
-
mismatch
static long mismatch(MemorySegment PREVIEW srcSegment, long srcFromOffset, long srcToOffset, MemorySegment PREVIEW dstSegment, long dstFromOffset, long dstToOffset) 查找并返回源段和目标段之间第一个不匹配的相对偏移量(以字节为单位)。更具体地说,将源段中偏移量为srcFromOffset到srcToOffset - 1的字节与目标段中偏移量为dstFromOffset到dstToOffset - 1的字节进行比较。如果指定范围内的两个段共享一个公共前缀,则返回的偏移量是公共前缀的长度,因此这两个段在各自段内的相对偏移处存在不匹配。如果一个段是另一个段的适当前缀,在指定范围内,则返回的偏移量是最小范围,因此相对偏移量仅对具有较大范围的段有效。否则,不存在不匹配并返回
-1。- 参数:
srcSegment- 源代码段。srcFromOffset- 要测试的源段中第一个字节的偏移量(含)。srcToOffset- 要测试的源段中最后一个字节的偏移量(不包括)。dstSegment- 目标段。dstFromOffset- 要测试的目标段中第一个字节的偏移量(含)。dstToOffset- 要测试的目标段中最后一个字节的偏移量(不包括)。- 返回:
- 源段和目标段之间第一个不匹配的相对偏移量(以字节为单位),如果不匹配则为 -1。
- 抛出:
IllegalStateException- 如果与srcSegment关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则srcSegment.scope().isAccessibleBy(T) == false。IllegalStateException- 如果与dstSegment关联的 scope 不是 活PREVIEW .WrongThreadException- 如果从线程T调用此方法,则dstSegment.scope().isAccessibleBy(T) == false。IndexOutOfBoundsException- 如果srcFromOffset < 0、srcToOffset < srcFromOffset或srcToOffset > srcSegment.byteSize()IndexOutOfBoundsException- 如果dstFromOffset < 0、dstToOffset < dstFromOffset或dstToOffset > dstSegment.byteSize()- 参见:
-
MemorySegment。