模块 java.base

接口 MemorySegment


public sealed interface MemorySegment
MemorySegment 是 Java 平台的预览 API。
程序只能在启用预览功能时使用 MemorySegment
预览功能可能会在未来的版本中删除,或升级为 Java 平台的永久功能。
内存段提供对连续内存区域的访问。

有两种内存段:

  • heap segment 由 Java 堆内的内存区域(“堆上”区域)支持并提供对内存区域的访问。
  • native segment 由 Java 堆外的内存区域(“堆外”区域)支持并提供访问权限。
可以通过调用 ofArray(int[]) 工厂方法之一来获取堆段。这些方法返回由保存指定 Java 数组的堆上区域支持的内存段。

本机段可以通过调用 allocateNative(long, long, SegmentScope) 工厂方法之一获得,该方法返回一个内存段,该内存段由新分配的堆外区域支持,具有给定的大小并与给定的对齐约束对齐。或者,可以通过 mapping 获得原生片段PREVIEW 将文件放入新的堆外区域(在某些系统中,此操作有时称为 mmap )。通过这种方式获得的段称为mapped段,其内容可以与底层内存映射文件坚持加载来往。

两种段都使用相同的方法读取和写入,称为 访问操作 。对内存段的访问操作始终且仅提供对获得该段的区域的访问。

内存段的特点

每个内存段都有一个 address ,表示为 long 值。段地址的性质取决于段的类型:
  • 堆段的地址不是物理地址,而是支持该段的内存区域内的偏移量。该区域位于 Java 堆内部,因此随着时间的推移,垃圾收集可能会导致该区域在物理内存中重新定位,但这不会暴露给 MemorySegment API 的客户端,他们会看到该区域支持的堆段的稳定 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);
 
对于更复杂的访问操作(例如结构化内存访问),客户端可以获得变量句柄PREVIEW 接受段和 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
 
或者,可以从 内存布局 获得复杂的 var 句柄PREVIEW 通过提供所谓的 layout path
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!
 
上面的代码创建了一个 100 字节长的本地段;然后,它创建一个从 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[] 1
byte[] 1
char[] 2
short[] 2
int[] 4
float[] 4
long[] 8
double[] 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
 
或者,他们可以使用 unaligned layout 调用访问操作。所有未对齐的布局常量(例如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
 
或者,客户可以获得 无界PREVIEW 地址值布局。当访问操作或传递给向下调用方法句柄的函数描述符使用无界地址值布局时,运行时将使用 maximal 大小(即 Long.MAX_VALUE )的本机段包装任何相应的原始地址。因此,可以直接访问这些段,如下所示:
 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
  • 字段详细信息

  • 方法详情

    • address

      long address()
      返回此内存段的地址。
      返回:
      该内存段的地址
    • array

      Optional <Object > array()
      返回与此内存段关联的 Java 数组(如果有)。
      返回:
      与此内存段关联的 Java 数组(如果有)
    • spliterator

      Spliterator <MemorySegment PREVIEW > spliterator(MemoryLayout PREVIEW  elementLayout)
      返回此内存段的拆分器。返回的拆分器报告 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 <MemorySegment PREVIEW > elements(MemoryLayout PREVIEW  elementLayout)
      返回此段中不相交切片(其大小与指定布局的大小匹配)的顺序 Stream。调用这个方法相当于下面的代码:
      StreamSupport.stream(segment.spliterator(elementLayout), false);
       
      参数:
      elementLayout - 用于拆分的布局。
      返回:
      在此段中的不相交切片上的顺序 Stream
      抛出:
      IllegalArgumentException - 如果 elementLayout 大小为零,或者以 elementLayout 大小为模的段大小大于零,如果该段在提供的布局中为 与对齐约束不兼容,或者 elementLayout 对齐方式大于其大小。
    • scope

      返回与此内存段关联的范围。
      返回:
      与此内存段关联的范围
    • byteSize

      long byteSize()
      返回此内存段的大小(以字节为单位)。
      返回:
      此内存段的大小(以字节为单位)
    • asSlice

      MemorySegment PREVIEW  asSlice(long offset, long newSize)
      在给定的偏移量处返回此内存段的一片。返回的段地址是该段的地址加上给定的偏移量;它的大小由给定的参数指定。
      参数:
      offset - 新的段基址偏移量(相对于该段的地址),以字节为单位指定。
      newSize - 新的段大小,以字节为单位指定。
      返回:
      此内存段的一部分。
      抛出:
      IndexOutOfBoundsException - 如果 offset < 0offset > byteSize()newSize < 0newSize > byteSize() - offset
      参见:
    • asSlice

      default MemorySegment PREVIEW  asSlice(long offset)
      在给定的偏移量处返回此内存段的一片。返回的段地址是该段的地址加上给定的偏移量;它的大小是通过从此段大小中减去指定的偏移量来计算的。

      相当于下面的代码:

      asSlice(offset, byteSize() - offset);
       
      参数:
      offset - 新的段基址偏移量(相对于该段的地址),以字节为单位指定。
      返回:
      此内存段的一部分。
      抛出:
      IndexOutOfBoundsException - 如果是 offset < 0offset > byteSize()
      参见:
    • isReadOnly

      boolean isReadOnly()
      如果此段是只读的,则返回 true
      返回:
      true ,如果该段是只读的
      参见:
    • asReadOnly

      MemorySegment PREVIEW  asReadOnly()
      返回此段的只读视图。生成的段将与该段相同,但尝试覆盖返回段的内容将导致运行时异常。
      返回:
      该段的只读视图
      参见:
    • isNative

      boolean isNative()
      如果此段是本机段,则返回 true。例如,使用 allocateNative(long, SegmentScope) (和相关)工厂或通过 包装 a 直接缓冲区 创建本机段。
      返回:
      true 如果此段是本机段。
    • isMapped

      boolean isMapped()
      如果此段是映射段,则返回 true。创建map内存段,例如使用 FileChannel.map(FileChannel.MapMode, long, long, SegmentScope) PREVIEW 工厂,或 包装 a 映射字节缓冲区
      返回:
      true 如果此段是映射段。
    • asOverlappingSlice

      Optional <MemorySegment PREVIEW > asOverlappingSlice(MemorySegment PREVIEW  other)
      返回此片段的一部分,该片段是此片段与提供的片段之间的重叠部分。

      如果可以找到至少两个由同一内存区域支持的切片 L1(来自 S1)和 L2(来自 S2),则称两个段 S1S2 重叠。因此,本国的 段不可能与堆段重叠;在这种情况下,或者当没有发生重叠时,返回 null

      参数:
      other - 测试与该段重叠的段。
      返回:
      该段的一部分(发生重叠的地方)。
    • segmentOffset

      long segmentOffset(MemorySegment PREVIEW  other)
      返回提供的段相对于此段的偏移量(以字节为单位)。

      偏移量是相对于该段地址的,可以是负值也可以是正值。例如,如果两个段都是本机段,或由同一数组支持的堆段,则可以按如下方式计算结果偏移量:

      other.address() - segment.address()
       
      如果段共享相同的地址,则返回 0。如果 other 是该段的一个切片,则偏移量始终为 0 <= x < this.byteSize()
      参数:
      other - 要检索偏移量的段。
      返回:
      提供的段的相对偏移量(以字节为单位)。
      抛出:
      UnsupportedOperationException - 如果两个段无法比较,例如因为它们属于不同类型,或者因为它们由不同的 Java 数组支持。
    • fill

      MemorySegment PREVIEW  fill(byte value)
      将值填充到此内存段中。

      更具体地说,将给定值填充到该段的每个地址中。等效于(但可能比)以下代码:

      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

      default MemorySegment PREVIEW  copyFrom(MemorySegment PREVIEW  src)
      执行从给定源段到此段的批量复制。更具体地说,源段中偏移量为 0src.byteSize() - 1 的字节被复制到偏移量为 0src.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

      default long mismatch(MemorySegment PREVIEW  other)
      查找并返回此段与给定其他段之间第一个不匹配的偏移量(以字节为单位)。偏移量是相对于每个段的 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

      byte[] toArray(ValueLayout.OfByte PREVIEW  elementLayout)
      将此内存段的内容复制到一个新的字节数组中。
      参数:
      elementLayout - 源元素布局。如果与布局关联的字节顺序与 原生顺序 不同,则将对每个数组元素执行字节交换操作。
      返回:
      一个新的字节数组,其内容是从此内存段复制的。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalStateException - 如果该段的内容无法复制到 byte[] 实例中,例如它的大小大于 Integer.MAX_VALUE
    • toArray

      short[] toArray(ValueLayout.OfShort PREVIEW  elementLayout)
      将此内存段的内容复制到一个新的短数组中。
      参数:
      elementLayout - 源元素布局。如果与布局关联的字节顺序与 原生顺序 不同,则将对每个数组元素执行字节交换操作。
      返回:
      一个新的短数组,其内容是从此内存段复制的。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalStateException - 如果此段的内容无法复制到 short[] 实例中,例如因为 byteSize() % 2 != 0byteSize() / 2 > Integer#MAX_VALUE
    • toArray

      char[] toArray(ValueLayout.OfChar PREVIEW  elementLayout)
      将此内存段的内容复制到一个新的 char 数组中。
      参数:
      elementLayout - 源元素布局。如果与布局关联的字节顺序与 原生顺序 不同,则将对每个数组元素执行字节交换操作。
      返回:
      一个新的 char 数组,其内容是从此内存段复制的。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalStateException - 如果此段的内容无法复制到 char[] 实例中,例如因为 byteSize() % 2 != 0byteSize() / 2 > Integer#MAX_VALUE
    • toArray

      int[] toArray(ValueLayout.OfInt PREVIEW  elementLayout)
      将此内存段的内容复制到一个新的 int 数组中。
      参数:
      elementLayout - 源元素布局。如果与布局关联的字节顺序与 原生顺序 不同,则将对每个数组元素执行字节交换操作。
      返回:
      一个新的 int 数组,其内容是从此内存段复制的。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalStateException - 如果此段的内容无法复制到 int[] 实例中,例如因为 byteSize() % 4 != 0byteSize() / 4 > Integer#MAX_VALUE
    • toArray

      float[] toArray(ValueLayout.OfFloat PREVIEW  elementLayout)
      将此内存段的内容复制到一个新的 float 数组中。
      参数:
      elementLayout - 源元素布局。如果与布局关联的字节顺序与 原生顺序 不同,则将对每个数组元素执行字节交换操作。
      返回:
      一个新的 float 数组,其内容是从此内存段复制的。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalStateException - 如果此段的内容无法复制到 float[] 实例中,例如因为 byteSize() % 4 != 0byteSize() / 4 > Integer#MAX_VALUE
    • toArray

      long[] toArray(ValueLayout.OfLong PREVIEW  elementLayout)
      将此内存段的内容复制到一个新的长数组中。
      参数:
      elementLayout - 源元素布局。如果与布局关联的字节顺序与 原生顺序 不同,则将对每个数组元素执行字节交换操作。
      返回:
      一个新的 long 数组,其内容是从此内存段复制的。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalStateException - 如果此段的内容无法复制到 long[] 实例中,例如因为 byteSize() % 8 != 0byteSize() / 8 > Integer#MAX_VALUE
    • toArray

      double[] toArray(ValueLayout.OfDouble PREVIEW  elementLayout)
      将此内存段的内容复制到一个新的双精度数组中。
      参数:
      elementLayout - 源元素布局。如果与布局关联的字节顺序与 原生顺序 不同,则将对每个数组元素执行字节交换操作。
      返回:
      一个新的双精度数组,其内容是从此内存段复制的。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalStateException - 如果此段的内容无法复制到 double[] 实例中,例如因为 byteSize() % 8 != 0byteSize() / 8 > Integer#MAX_VALUE
    • getUtf8String

      default String  getUtf8String(long offset)
      从此段中给定偏移处读取 UTF-8 编码、以 null 结尾的字符串。

      此方法始终用此字符集的默认替换字符串替换格式错误的输入和不可映射的字符序列。当需要对解码过程进行更多控制时,应使用 CharsetDecoder 类。

      参数:
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      返回:
      一个 Java 字符串,由从给定起始地址读取的字节构成,直到(但不包括)第一个 '\0' 终止符(假设找到一个)。
      抛出:
      IllegalArgumentException - 如果 UTF-8 字符串的大小大于平台支持的最大字符串。
      IndexOutOfBoundsException - 如果是 offset < 0S + offset > byteSize() ,其中 S 是 UTF-8 字符串的大小(包括终止符)。
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
    • setUtf8String

      default void setUtf8String(long offset, String  str)
      以给定的偏移量将给定的字符串写入此段,使用 UTF-8 编码将其转换为以 null 结尾的字节序列。

      此方法始终用此字符集的默认替换字符串替换格式错误的输入和不可映射的字符序列。当需要对解码过程进行更多控制时,应使用 CharsetDecoder 类。

      如果给定的字符串包含任何 '\0' 个字符,它们也将被复制。这意味着,根据用于读取字符串的方法(例如 getUtf8String(long) ),再次读取时字符串将被截断。

      参数:
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。这个写操作的最终地址可以表示为address() + offset
      str - 要写入此段的 Java 字符串。
      抛出:
      IndexOutOfBoundsException - 如果是 offset < 0str.getBytes().length() + offset >= byteSize()
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
    • ofBuffer

      static MemorySegment PREVIEW  ofBuffer(Buffer  buffer)
      创建一个内存段,该内存段由支持给定 Buffer 实例的同一内存区域支持。该段相对于缓冲区的位置(包括)开始,并相对于缓冲区的限制(不包括)结束。

      如果缓冲区是 只读 ,则生成的段也将是 只读 。此外,如果缓冲区是 直接缓冲区 ,则返回的段是本机段;否则返回的内存段是堆段。

      与返回的段关联的范围 S 计算如下:

      • 如果通过在范围为 S' 的内存段上调用 asByteBuffer() 获得缓冲区,则 S = S' ;或者
      • 如果缓冲区是堆缓冲区,则 S全球范围PREVIEW ;或者
      • 如果缓冲区是直接缓冲区,则 S 是始终处于活动状态并保持缓冲区可访问的作用域。因此,只要返回的段可到达,支持缓冲区实例的堆外内存区域将保持可用。
      参数:
      buffer - 要变成新内存段的缓冲区实例。
      返回:
      从给定的缓冲区实例派生的内存段。
      抛出:
      IllegalArgumentException - 如果提供的 buffer 是堆缓冲区但不受数组支持。例如,通过 (CharBuffer.wrap(CharSequence) CharBuffer.wrap(char[], int, int) 直接或间接获得的缓冲区不受数组支持。
    • ofArray

      static MemorySegment PREVIEW  ofArray(byte[] byteArray)
      创建由保存给定字节数组的堆上内存区域支持的堆段。返回的段与 全球范围 相关联PREVIEW 并且其 address() 设置为零。
      参数:
      byteArray - 支持堆内存段的原始数组。
      返回:
      由字节数组支持的堆内存段。
    • ofArray

      static MemorySegment PREVIEW  ofArray(char[] charArray)
      创建一个由保存给定 char 数组的堆上内存区域支持的堆段。返回的段与 全球范围 相关联PREVIEW 并且其 address() 设置为零。
      参数:
      charArray - 支持堆段的原始数组。
      返回:
      由 char 数组支持的堆内存段。
    • ofArray

      static MemorySegment PREVIEW  ofArray(short[] shortArray)
      创建一个由保存给定短数组的堆上内存区域支持的堆段。返回的段与 全球范围 相关联PREVIEW 并且其 address() 设置为零。
      参数:
      shortArray - 支持堆段的原始数组。
      返回:
      由短数组支持的堆内存段。
    • ofArray

      static MemorySegment PREVIEW  ofArray(int[] intArray)
      创建由保存给定 int 数组的堆上内存区域支持的堆段。返回的段与 全球范围 相关联PREVIEW 并且其 address() 设置为零。
      参数:
      intArray - 支持堆段的原始数组。
      返回:
      由 int 数组支持的堆内存段。
    • ofArray

      static MemorySegment PREVIEW  ofArray(float[] floatArray)
      创建一个由保存给定浮点数组的堆上内存区域支持的堆段。返回的段与 全球范围 相关联PREVIEW 并且其 address() 设置为零。
      参数:
      floatArray - 支持堆段的原始数组。
      返回:
      由浮点数组支持的堆内存段。
    • ofArray

      static MemorySegment PREVIEW  ofArray(long[] longArray)
      创建一个由保存给定长数组的堆上内存区域支持的堆段。返回的段与 全球范围 相关联PREVIEW 并且其 address() 设置为零。
      参数:
      longArray - 支持堆段的原始数组。
      返回:
      由长数组支持的堆内存段。
    • ofArray

      static MemorySegment PREVIEW  ofArray(double[] doubleArray)
      创建由保存给定双精度数组的堆上内存区域支持的堆段。返回的段与 全球范围 相关联PREVIEW 并且其 address() 设置为零。
      参数:
      doubleArray - 支持堆段的原始数组。
      返回:
      由双数组支持的堆内存段。
    • ofAddress

      static MemorySegment PREVIEW  ofAddress(long address)
      从给定的 地址值 创建一个零长度的本机段。返回的段与 全球范围 相关联PREVIEW .

      这等效于以下代码:

       ofAddress(address, 0);
       
      参数:
      address - 返回的本机段的地址。
      返回:
      具有给定地址的零长度本机段。
    • ofAddress

      static MemorySegment PREVIEW  ofAddress(long address, long byteSize)
      创建具有给定大小和 地址值 的本机段。返回的段与 全球范围 相关联PREVIEW .

      这等效于以下代码:

       ofAddress(address, byteSize, SegmentScope.global());
       
      这个方法是restricted 。受限方法是不安全的,如果使用不当,它们的使用可能会使 JVM 崩溃,或者更糟的是,无声地导致内存损坏。因此,客户应避免依赖受限的方法,并尽可能使用安全和受支持的功能。
      参数:
      address - 返回的本机段的地址。
      byteSize - 返回的本机段的大小(以字节为单位)。
      返回:
      具有给定地址和大小的零长度本机段。
      抛出:
      IllegalArgumentException - 如果 byteSize < 0
      IllegalCallerException - 如果调用者所在的模块未启用本机访问。
    • ofAddress

      static MemorySegment PREVIEW  ofAddress(long address, long byteSize, SegmentScope PREVIEW  scope)
      创建具有给定大小、地址和范围的本机段。当与自定义内存源(例如自定义分配器)交互时,此方法很有用,其中一些底层内存区域的地址通常是从外部代码获得的(通常作为普通的 long 值)。

      返回的段不是只读的(参见 isReadOnly() ),并且与提供的范围相关联。

      这等效于以下代码:

       ofAddress(address, byteSize, scope, null);
       
      这个方法是restricted 。受限方法是不安全的,如果使用不当,它们的使用可能会使 JVM 崩溃,或者更糟的是,无声地导致内存损坏。因此,客户应避免依赖受限的方法,并尽可能使用安全和受支持的功能。
      参数:
      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

      static MemorySegment PREVIEW  allocateNative(long byteSize, SegmentScope PREVIEW  scope)
      创建具有给定大小(以字节为单位)和范围的本机段。

      与返回的本机段关联的生存期堆外内存区域由提供的范围确定。当作用域变为 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 < 0byteAlignment <= 0byteAlignment 不是 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)
      执行从源段到目标段的批量复制。更具体地说,源段中偏移量为 srcOffsetsrcOffset + bytes - 1 的字节被复制到偏移量为 dstOffsetdstOffset + bytes - 1 的目标段中。

      如果源段与这个段重叠,那么复制就好像源段中偏移量srcOffsetsrcOffset + bytes - 1的字节首先被复制到一个大小为bytes的临时段,然后临时段的内容被复制到偏移量为 dstOffsetdstOffset + 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(),或者如果 srcOffsetdstOffsetbytes< 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 是元素布局的字节大小,则将源段中偏移量为 srcOffsetsrcOffset + (elementCount * S) - 1 的字节复制到偏移量为 dstOffsetdstOffset + (elementCount * S) - 1 的目标段中。

      复制以元素方式进行:源段中的字节被解释为布局为 srcElementLayout 的元素序列,而目标段中的字节被解释为布局为 dstElementLayout 的元素序列。两个元素布局必须具有相同的大小 S 。如果两个元素布局的字节顺序不同,则在复制操作期间相应地交换对应于每个要复制的元素的字节。

      如果源段与这个段重叠,那么复制就好像源段中偏移量srcOffsetsrcOffset + (elementCount * S) - 1处的字节首先被复制到一个大小为bytes的临时段,然后临时段的内容被复制到偏移量为 dstOffsetdstOffset + (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 是元素布局的字节大小,或者如果 srcOffsetdstOffsetelementCount< 0
      UnsupportedOperationException - 如果目标段是只读的(请参阅 isReadOnly() )。
    • get

      default byte get(ValueLayout.OfByte PREVIEW  layout, long offset)
      使用给定布局从给定偏移量处的该段中读取一个字节。
      参数:
      layout - 要读取的内存区域的布局。
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      返回:
      从该段读取的字节值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
    • set

      default void set(ValueLayout.OfByte PREVIEW  layout, long offset, byte value)
      使用给定的布局在给定的偏移量处将一个字节写入该段。
      参数:
      layout - 要写入的内存区域的布局。
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      value - 要写入的字节值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
      UnsupportedOperationException - 如果此段是 只读
    • get

      default boolean get(ValueLayout.OfBoolean PREVIEW  layout, long offset)
      使用给定布局从给定偏移量处的该段读取boolean。
      参数:
      layout - 要读取的内存区域的布局。
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      返回:
      从该段读取的boolean。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
    • set

      default void set(ValueLayout.OfBoolean PREVIEW  layout, long offset, boolean value)
      使用给定的布局在给定的偏移量处将boolean写入该段。
      参数:
      layout - 要写入的内存区域的布局。
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      value - 要写入的boolean。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
      UnsupportedOperationException - 如果此段是 只读
    • get

      default char get(ValueLayout.OfChar PREVIEW  layout, long offset)
      以给定的偏移量和给定的布局从该段中读取一个字符。
      参数:
      layout - 要读取的内存区域的布局。
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      返回:
      从该段读取的 char 值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
    • set

      default void set(ValueLayout.OfChar PREVIEW  layout, long offset, char value)
      使用给定的布局在给定的偏移量处将 char 写入该段。
      参数:
      layout - 要写入的内存区域的布局。
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      value - 要写入的 char 值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
      UnsupportedOperationException - 如果此段是 只读
    • get

      default short get(ValueLayout.OfShort PREVIEW  layout, long offset)
      使用给定的布局,在给定的偏移量处从该段读取一个短片。
      参数:
      layout - 要读取的内存区域的布局。
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      返回:
      从该段读取的短值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
    • set

      default void set(ValueLayout.OfShort PREVIEW  layout, long offset, short value)
      使用给定的布局,在给定的偏移量处将一个 short 写入该段。
      参数:
      layout - 要写入的内存区域的布局。
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      value - 要写入的短值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
      UnsupportedOperationException - 如果此段是 只读
    • get

      default int get(ValueLayout.OfInt PREVIEW  layout, long offset)
      使用给定布局从给定偏移量处的该段读取一个 int。
      参数:
      layout - 要读取的内存区域的布局。
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      返回:
      从该段读取的 int 值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
    • set

      default void set(ValueLayout.OfInt PREVIEW  layout, long offset, int value)
      使用给定的布局在给定的偏移量处将一个 int 写入该段。
      参数:
      layout - 要写入的内存区域的布局。
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      value - 要写入的 int 值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
      UnsupportedOperationException - 如果此段是 只读
    • get

      default float get(ValueLayout.OfFloat PREVIEW  layout, long offset)
      使用给定布局从给定偏移量处的该段读取一个浮点数。
      参数:
      layout - 要读取的内存区域的布局。
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      返回:
      从该段读取的浮点值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
    • set

      default void set(ValueLayout.OfFloat PREVIEW  layout, long offset, float value)
      使用给定的布局在给定的偏移量处将浮点数写入该段。
      参数:
      layout - 要写入的内存区域的布局。
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      value - 要写入的浮点值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
      UnsupportedOperationException - 如果此段是 只读
    • get

      default long get(ValueLayout.OfLong PREVIEW  layout, long offset)
      使用给定的布局在给定的偏移量处从该段读取一个 long。
      参数:
      layout - 要读取的内存区域的布局。
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      返回:
      从该段读取的长值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
    • set

      default void set(ValueLayout.OfLong PREVIEW  layout, long offset, long value)
      使用给定的布局在给定的偏移量处将 long 写入该段。
      参数:
      layout - 要写入的内存区域的布局。
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      value - 要写入的 long 值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
      UnsupportedOperationException - 如果此段是 只读
    • get

      default double get(ValueLayout.OfDouble PREVIEW  layout, long offset)
      使用给定布局从给定偏移量处的该段读取双精度值。
      参数:
      layout - 要读取的内存区域的布局。
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      返回:
      从该段读取的双精度值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
    • set

      default void set(ValueLayout.OfDouble PREVIEW  layout, long offset, double value)
      使用给定的布局在给定的偏移量处将双精度值写入此段。
      参数:
      layout - 要写入的内存区域的布局。
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      value - 要写入的双精度值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
      UnsupportedOperationException - 如果此段是 只读
    • get

      default MemorySegment PREVIEW  get(ValueLayout.OfAddress PREVIEW  layout, long offset)
      以给定的偏移量和给定的布局从该段中读取一个地址。读取地址包装在与 全球范围 关联的本机段中PREVIEW .在正常情况下,返回段的大小为 0 。但是,如果提供的布局是 无界PREVIEW 地址布局,则返回段的大小为 Long.MAX_VALUE
      参数:
      layout - 要读取的内存区域的布局。
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      返回:
      包装从该段读取的地址的本机段。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
    • set

      default void set(ValueLayout.OfAddress PREVIEW  layout, long offset, MemorySegment PREVIEW  value)
      使用给定的布局在给定的偏移量处将地址写入此段。
      参数:
      layout - 要写入的内存区域的布局。
      offset - 将发生此访问操作的字节偏移量(相对于此段地址)。
      value - 要写入的地址值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
      UnsupportedOperationException - 如果此段是 只读
      UnsupportedOperationException - 如果 value 不是 本国的 段。
    • getAtIndex

      default char getAtIndex(ValueLayout.OfChar PREVIEW  layout, long index)
      从给定索引处的该段中读取一个字符,按给定布局大小缩放。
      参数:
      layout - 要读取的内存区域的布局。
      index - 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为 (index * layout.byteSize())
      返回:
      从该段读取的 char 值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
    • setAtIndex

      default void setAtIndex(ValueLayout.OfChar PREVIEW  layout, long index, char value)
      在给定索引处将 char 写入此段,按给定布局大小缩放。
      参数:
      layout - 要写入的内存区域的布局。
      index - 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为 (index * layout.byteSize())
      value - 要写入的 char 值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
      UnsupportedOperationException - 如果此段是 只读
    • getAtIndex

      default short getAtIndex(ValueLayout.OfShort PREVIEW  layout, long index)
      从给定索引处的该段读取一个短片,按给定布局大小缩放。
      参数:
      layout - 要读取的内存区域的布局。
      index - 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为 (index * layout.byteSize())
      返回:
      从该段读取的短值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
    • setAtIndex

      default void setAtIndex(ValueLayout.OfShort PREVIEW  layout, long index, short value)
      在给定的索引处写入一个 short 到该段,按给定的布局大小缩放。
      参数:
      layout - 要写入的内存区域的布局。
      index - 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为 (index * layout.byteSize())
      value - 要写入的短值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
      UnsupportedOperationException - 如果此段是 只读
    • getAtIndex

      default int getAtIndex(ValueLayout.OfInt PREVIEW  layout, long index)
      从给定索引处的该段读取一个 int,按给定布局大小缩放。
      参数:
      layout - 要读取的内存区域的布局。
      index - 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为 (index * layout.byteSize())
      返回:
      从该段读取的 int 值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
    • setAtIndex

      default void setAtIndex(ValueLayout.OfInt PREVIEW  layout, long index, int value)
      在给定的索引处将一个 int 写入此段,按给定的布局大小缩放。
      参数:
      layout - 要写入的内存区域的布局。
      index - 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为 (index * layout.byteSize())
      value - 要写入的 int 值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
      UnsupportedOperationException - 如果此段是 只读
    • getAtIndex

      default float getAtIndex(ValueLayout.OfFloat PREVIEW  layout, long index)
      从给定索引处的该段读取浮点数,按给定布局大小缩放。
      参数:
      layout - 要读取的内存区域的布局。
      index - 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为 (index * layout.byteSize())
      返回:
      从该段读取的浮点值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
    • setAtIndex

      default void setAtIndex(ValueLayout.OfFloat PREVIEW  layout, long index, float value)
      在给定索引处将浮点数写入此段,按给定布局大小缩放。
      参数:
      layout - 要写入的内存区域的布局。
      index - 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为 (index * layout.byteSize())
      value - 要写入的浮点值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
      UnsupportedOperationException - 如果此段是 只读
    • getAtIndex

      default long getAtIndex(ValueLayout.OfLong PREVIEW  layout, long index)
      从给定索引处的该段读取 long,按给定布局大小缩放。
      参数:
      layout - 要读取的内存区域的布局。
      index - 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为 (index * layout.byteSize())
      返回:
      从该段读取的长值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
    • setAtIndex

      default void setAtIndex(ValueLayout.OfLong PREVIEW  layout, long index, long value)
      在给定索引处将 long 写入此段,按给定布局大小缩放。
      参数:
      layout - 要写入的内存区域的布局。
      index - 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为 (index * layout.byteSize())
      value - 要写入的 long 值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
      UnsupportedOperationException - 如果此段是 只读
    • getAtIndex

      default double getAtIndex(ValueLayout.OfDouble PREVIEW  layout, long index)
      从给定索引处的该段读取双精度值,按给定布局大小缩放。
      参数:
      layout - 要读取的内存区域的布局。
      index - 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为 (index * layout.byteSize())
      返回:
      从该段读取的双精度值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
    • setAtIndex

      default void setAtIndex(ValueLayout.OfDouble PREVIEW  layout, long index, double value)
      在给定索引处将双精度值写入此段,按给定布局大小缩放。
      参数:
      layout - 要写入的内存区域的布局。
      index - 逻辑索引。访问操作将发生的字节偏移量(相对于该段地址)可以表示为 (index * layout.byteSize())
      value - 要写入的双精度值。
      抛出:
      IllegalStateException - 如果与该段关联的 scope 不是 PREVIEW .
      WrongThreadException - 如果从线程 T 调用此方法,则 scope().isAccessibleBy(T) == false
      IllegalArgumentException - 如果访问操作在提供的布局中为 与对齐约束不兼容,或者布局对齐方式大于其大小。
      IndexOutOfBoundsException - 当访问操作落在内存段的 spatial bounds 之外时。
      UnsupportedOperationException - 如果此段是 只读
    • getAtIndex

      default MemorySegment PREVIEW  getAtIndex(ValueLayout.OfAddress PREVIEW  layout, long index)
      从给定索引处的给定段读取地址,按给定布局大小缩放。读取地址包装在与 全球范围 关联的本机段中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

      boolean equals(Object  that)
      比较指定对象与此内存段是否相等。返回 true 当且仅当指定的对象也是一个内存段,并且如果两个段引用相同的位置,在某个内存区域。更具体地说,对于被视为相等的两个段 s1s2,以下所有条件都必须为真:
      • s1.array().equals(s2.array()) ,即两个段必须是同一类;两者都是 原生片段 ,由堆外内存支持,或者两者都由相同的堆上 Java 数组支持;
      • s1.address() == s2.address() ,即两个段的地址应该相同。这意味着这两个段要么引用某个堆外区域中的相同位置,要么引用其关联的 Java 数组实例中的相同位置。
      重写:
      equals 在类 Object
      API 注意:
      该方法不对两个内存段的内容进行结构比较。客户端可以改用 mismatch(MemorySegment) 方法在结构上比较内存段。请注意,此方法确实not比较两个片段的时间和空间边界。因此,它适合执行地址检查,例如检查本机段是否具有 NULL 地址。
      参数:
      that - 要与此内存段进行相等比较的对象。
      返回:
      true 如果指定的对象等于这个内存段。
      参见:
    • hashCode

      int hashCode()
      返回此内存段的哈希码值。
      重写:
      hashCode 在类 Object
      返回:
      此内存段的哈希码值
      参见:
    • 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)
      查找并返回源段和目标段之间第一个不匹配的相对偏移量(以字节为单位)。更具体地说,将源段中偏移量为srcFromOffsetsrcToOffset - 1 的字节与目标段中偏移量为dstFromOffsetdstToOffset - 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 < 0srcToOffset < srcFromOffsetsrcToOffset > srcSegment.byteSize()
      IndexOutOfBoundsException - 如果 dstFromOffset < 0dstToOffset < dstFromOffsetdstToOffset > dstSegment.byteSize()
      参见: