- 函数式接口:
- 这是一个函数式接口,因此可以用作lambda表达式或方法引用的赋值目标。
SegmentAllocator
是Java平台的预览API。
预览功能可能会在将来的版本中被移除,或升级为Java平台的永久功能。
一个可用于分配内存段预览的对象。实现此接口的客户端必须实现
allocate(long, long)
方法。段分配器定义了几种方法,可以用于从各种Java值(如基本类型和数组)创建段。
SegmentAllocator
是一个函数式接口。客户端可以通过lambda表达式或方法引用轻松获取新的段分配器:
SegmentAllocator autoAllocator = (byteSize, byteAlignment) -> Arena.ofAuto().allocate(byteSize, byteAlignment);
此接口定义了常用分配器的工厂:
slicingAllocator(MemorySegment)
获取一个高效的切片分配器,其中内存通过反复切片提供的内存段进行分配;prefixAllocator(MemorySegment)
获取一个包装段并在每次新的分配请求时回收其内容的分配器。
将段分配器传递给API在客户端希望将某个操作的结果(由API执行)存储在内存段中的情况下特别有用。例如,downcall方法句柄预览可以接受一个额外的SegmentAllocator
预览参数,如果底层的外部函数已知通过值返回结构。实际上,分配器参数告诉链接器在哪里存储外部函数的返回值。
- API注释:
-
除非另有说明,
allocate(long, long)
方法不是线程安全的。此外,由段分配器分配的内存段可以关联不同的生命周期,甚至可以由重叠的内存区域支持。因此,客户端通常只应与自己拥有的段分配器交互。
-
Method Summary
Modifier and TypeMethodDescriptiondefault MemorySegmentPREVIEW
allocate
(long byteSize) 分配具有给定大小的内存段。allocate
(long byteSize, long byteAlignment) 分配具有给定大小和对齐约束的内存段。default MemorySegmentPREVIEW
allocate
(AddressLayoutPREVIEW layout, MemorySegmentPREVIEW value) 分配具有给定布局并使用给定地址值初始化的内存段。default MemorySegmentPREVIEW
allocate
(MemoryLayoutPREVIEW layout) 分配具有给定布局的内存段。default MemorySegmentPREVIEW
allocate
(ValueLayout.OfBytePREVIEW layout, byte value) 分配具有给定布局并使用给定字节值初始化的内存段。default MemorySegmentPREVIEW
allocate
(ValueLayout.OfCharPREVIEW layout, char value) 分配具有给定布局并使用给定字符值初始化的内存段。default MemorySegmentPREVIEW
allocate
(ValueLayout.OfDoublePREVIEW layout, double value) 分配具有给定布局并使用给定双精度值初始化的内存段。default MemorySegmentPREVIEW
allocate
(ValueLayout.OfFloatPREVIEW layout, float value) 分配具有给定布局并使用给定浮点值初始化的内存段。default MemorySegmentPREVIEW
allocate
(ValueLayout.OfIntPREVIEW layout, int value) 分配具有给定布局并使用给定整数值初始化的内存段。default MemorySegmentPREVIEW
allocate
(ValueLayout.OfLongPREVIEW layout, long value) 分配具有给定布局并使用给定长整型值初始化的内存段。default MemorySegmentPREVIEW
allocate
(ValueLayout.OfShortPREVIEW layout, short value) 分配具有给定布局并使用给定短整型值初始化的内存段。default MemorySegmentPREVIEW
allocateArray
(MemoryLayoutPREVIEW elementLayout, long count) 分配具有给定元素布局和大小的内存段。default MemorySegmentPREVIEW
allocateArray
(ValueLayout.OfBytePREVIEW elementLayout, byte... elements) 分配具有给定布局并使用给定字节元素初始化的内存段。default MemorySegmentPREVIEW
allocateArray
(ValueLayout.OfCharPREVIEW elementLayout, char... elements) 分配具有给定布局并使用给定字符元素初始化的内存段。default MemorySegmentPREVIEW
allocateArray
(ValueLayout.OfDoublePREVIEW elementLayout, double... elements) 分配具有给定布局并使用给定双精度元素初始化的内存段。default MemorySegmentPREVIEW
allocateArray
(ValueLayout.OfFloatPREVIEW elementLayout, float... elements) 分配具有给定布局并使用给定浮点元素初始化的内存段。default MemorySegmentPREVIEW
allocateArray
(ValueLayout.OfIntPREVIEW elementLayout, int... elements) 分配具有给定布局并使用给定整数元素初始化的内存段。default MemorySegmentPREVIEW
allocateArray
(ValueLayout.OfLongPREVIEW elementLayout, long... elements) 分配具有给定布局并使用给定长整型元素初始化的内存段。default MemorySegmentPREVIEW
allocateArray
(ValueLayout.OfShortPREVIEW elementLayout, short... elements) 分配具有给定布局并使用给定短整型元素初始化的内存段。default MemorySegmentPREVIEW
allocateUtf8String
(String str) 将Java字符串转换为UTF-8编码的以null结尾的C字符串,并将结果存储到内存段中。static SegmentAllocatorPREVIEW
prefixAllocator
(MemorySegmentPREVIEW segment) 返回一个段分配器,通过回收单个段响应分配请求。static SegmentAllocatorPREVIEW
slicingAllocator
(MemorySegmentPREVIEW segment) 返回一个段分配器,通过从提供的段中获取连续切片来响应分配请求。
-
Method Details
-
allocateUtf8String
将Java字符串转换为UTF-8编码的以null结尾的C字符串,并将结果存储到内存段中。此方法始终使用此字符集的默认替换字节数组替换格式不正确的输入和无法映射的字符序列。当需要对编码过程进行更多控制时,应使用
CharsetEncoder
类。如果给定字符串包含任何
'\0'
字符,它们也将被复制。这意味着,根据用于读取字符串的方法,例如MemorySegment.getUtf8String(long)
预览,再次读取时字符串将显示为截断。- 实现要求:
-
此方法的默认实现将Java字符串的内容复制到通过调用
this.allocate(str.length() + 1)
获得的新内存段中。 - 参数:
-
str
- 要转换为C字符串的Java字符串。 - 返回:
- 包含转换后的C字符串的新本地段。
-
allocate
分配具有给定布局并使用给定字节值初始化的内存段。- 实现要求:
-
此方法的默认实现调用
this.allocate(layout)
。 - 参数:
-
layout
- 要分配的内存块的布局。 -
value
- 要设置在新分配的内存块上的值。 - 返回:
- 新分配的内存块的段。
-
allocate
分配具有给定布局并使用给定字符值初始化的内存段。- 实现要求:
-
此方法的默认实现调用
this.allocate(layout)
。 - 参数:
-
layout
- 要分配的内存块的布局。 -
value
- 要设置在新分配的内存块上的值。 - 返回:
- 新分配的内存块的段。
-
allocate
分配具有给定布局并使用给定短整型值初始化的内存段。- 实现要求:
-
此方法的默认实现调用
this.allocate(layout)
。 - 参数:
-
layout
- 要分配的内存块的布局。 -
value
- 要设置在新分配的内存块上的值。 - 返回:
- 新分配的内存块的段。
-
allocate
分配具有给定布局并使用给定整数值初始化的内存段。- 实现要求:
-
此方法的默认实现调用
this.allocate(layout)
。 - 参数:
-
layout
- 要分配的内存块的布局。 -
value
- 要设置在新分配的内存块上的值。 - 返回:
- 新分配的内存块的段。
-
allocate
分配具有给定布局并使用给定浮点值初始化的内存段。- 实现要求:
-
此方法的默认实现调用
this.allocate(layout)
。 - 参数:
-
layout
- 要分配的内存块的布局。 -
value
- 要设置在新分配的内存块上的值。 - 返回:
- 新分配的内存块的段。
-
allocate
分配具有给定布局并使用给定长整型值初始化的内存段。- 实现要求:
-
此方法的默认实现调用
this.allocate(layout)
。 - 参数:
-
layout
- 要分配的内存块的布局。 -
value
- 要设置在新分配的内存块上的值。 - 返回:
- 新分配的内存块的段。
-
allocate
分配具有给定布局的内存段,并用给定的双精度值进行初始化。- 实现要求:
-
该方法的默认实现调用
this.allocate(layout)
。 - 参数:
-
layout
- 要分配的内存块的布局。 -
value
- 要设置在新分配的内存块上的值。 - 返回:
- 新分配的内存块的段。
-
allocate
分配具有给定布局的内存段,并用给定的地址值进行初始化。地址值可能会根据平台地址大小进行缩小(请参阅ValueLayout.ADDRESS
预览)。- 实现要求:
-
该方法的默认实现调用
this.allocate(layout)
。 - 参数:
-
layout
- 要分配的内存块的布局。 -
value
- 要设置在新分配的内存块上的值。 - 返回:
- 新分配的内存块的段。
-
allocateArray
default MemorySegmentPREVIEW allocateArray(ValueLayout.OfBytePREVIEW elementLayout, byte... elements) 分配具有给定布局的内存段,并用给定的字节元素进行初始化。- 实现要求:
-
该方法的默认实现调用
this.allocateArray(layout, array.length)
。 - 参数:
-
elementLayout
- 要分配的数组的元素布局。 -
elements
- 要复制到新分配的内存块的字节元素。 - 返回:
- 新分配的内存块的段。
-
allocateArray
default MemorySegmentPREVIEW allocateArray(ValueLayout.OfShortPREVIEW elementLayout, short... elements) 分配具有给定布局的内存段,并用给定的短整型元素进行初始化。- 实现要求:
-
该方法的默认实现调用
this.allocateArray(layout, array.length)
。 - 参数:
-
elementLayout
- 要分配的数组的元素布局。 -
elements
- 要复制到新分配的内存块的短整型元素。 - 返回:
- 新分配的内存块的段。
-
allocateArray
default MemorySegmentPREVIEW allocateArray(ValueLayout.OfCharPREVIEW elementLayout, char... elements) 分配具有给定布局的内存段,并用给定的字符元素进行初始化。- 实现要求:
-
该方法的默认实现调用
this.allocateArray(layout, array.length)
。 - 参数:
-
elementLayout
- 要分配的数组的元素布局。 -
elements
- 要复制到新分配的内存块的字符元素。 - 返回:
- 新分配的内存块的段。
-
allocateArray
分配具有给定布局的内存段,并用给定的整型元素进行初始化。- 实现要求:
-
该方法的默认实现调用
this.allocateArray(layout, array.length)
。 - 参数:
-
elementLayout
- 要分配的数组的元素布局。 -
elements
- 要复制到新分配的内存块的整型元素。 - 返回:
- 新分配的内存块的段。
-
allocateArray
default MemorySegmentPREVIEW allocateArray(ValueLayout.OfFloatPREVIEW elementLayout, float... elements) 分配具有给定布局的内存段,并用给定的浮点型元素进行初始化。- 实现要求:
-
该方法的默认实现调用
this.allocateArray(layout, array.length)
。 - 参数:
-
elementLayout
- 要分配的数组的元素布局。 -
elements
- 要复制到新分配的内存块的浮点型元素。 - 返回:
- 新分配的内存块的段。
-
allocateArray
default MemorySegmentPREVIEW allocateArray(ValueLayout.OfLongPREVIEW elementLayout, long... elements) 分配具有给定布局的内存段,并用给定的长整型元素进行初始化。- 实现要求:
-
该方法的默认实现调用
this.allocateArray(layout, array.length)
。 - 参数:
-
elementLayout
- 要分配的数组的元素布局。 -
elements
- 要复制到新分配的内存块的长整型元素。 - 返回:
- 新分配的内存块的段。
-
allocateArray
default MemorySegmentPREVIEW allocateArray(ValueLayout.OfDoublePREVIEW elementLayout, double... elements) 分配具有给定布局的内存段,并用给定的双精度元素进行初始化。- 实现要求:
-
该方法的默认实现调用
this.allocateArray(layout, array.length)
。 - 参数:
-
elementLayout
- 要分配的数组的元素布局。 -
elements
- 要复制到新分配的内存块的双精度元素。 - 返回:
- 新分配的内存块的段。
-
allocate
分配具有给定布局的内存段。- 实现要求:
-
该方法的默认实现调用
this.allocate(layout.byteSize(), layout.byteAlignment())
。 - 参数:
-
layout
- 要分配的内存块的布局。 - 返回:
- 新分配的内存块的段。
-
allocateArray
分配具有给定元素布局和大小的内存段。- 实现要求:
-
该方法的默认实现调用
this.allocate(MemoryLayout.sequenceLayout(count, elementLayout))
。 - 参数:
-
elementLayout
- 数组元素布局。 -
count
- 数组元素计数。 - 返回:
- 新分配的内存块的段。
- 抛出:
-
IllegalArgumentException
- 如果elementLayout.byteSize() * count
溢出。 -
IllegalArgumentException
- 如果count < 0
。
-
allocate
分配具有给定大小的内存段。- 实现要求:
-
该方法的默认实现调用
this.allocate(byteSize, 1)
。 - 参数:
-
byteSize
- 要分配的内存块的大小(以字节为单位)。 - 返回:
- 新分配的内存块的段。
- 抛出:
-
IllegalArgumentException
- 如果byteSize < 0
-
allocate
分配具有给定大小和对齐约束的内存段。- 参数:
-
byteSize
- 要分配的内存块的大小(以字节为单位)。 -
byteAlignment
- 要分配的内存块的对齐方式(以字节为单位)。 - 返回:
- 新分配的内存块的段。
- 抛出:
-
IllegalArgumentException
- 如果byteSize < 0
,byteAlignment <= 0
,或者byteAlignment
不是2的幂。
-
slicingAllocator
返回一个段分配器,该分配器通过从提供的段中获取连续的切片来响应分配请求。每个新的分配请求将返回一个从当前偏移开始的新切片(模除额外填充以满足对齐约束),具有给定的大小。当无法找到具有请求大小和对齐的提供段的切片时,返回的分配器会抛出
IndexOutOfBoundsException
。- 实现说明:
- 切片分配器不是线程安全的。
- 参数:
-
segment
- 返回的分配器应该从中切片的段。 - 返回:
- 一个新的切片分配器
-
prefixAllocator
返回一个段分配器,该分配器通过回收单个段来响应分配请求。每个新的分配请求将返回一个从段偏移0
开始的新切片,因此称为前缀分配器。等效于以下代码(但可能更有效):MemorySegment segment = ... SegmentAllocator prefixAllocator = (size, align) -> segment.asSlice(0, size, align);
IndexOutOfBoundsException
。- API说明:
- 前缀分配器可用于限制分配请求,以防客户端知道在进行后续分配请求之前已完全处理了分配的段的内容。
- 实现说明:
- 虽然前缀分配器是线程安全的,但在同一回收分配器上的并发访问可能导致一个线程覆盖另一个线程写入底层段的内容。
- 参数:
-
segment
- 要由返回的分配器回收的内存段。 - 返回:
- 在每个新的分配请求上回收现有段的分配器。
-
SegmentAllocator
。