如何像Java 21预览版一样在Java 20预览版中重新解释内存分段:

内存段重新解释(Long NewSize)-返回一个新的内存段,该内存段的地址和作用域与该段相同,但大小是否与提供的相同?

请参考以下CCODE代码片段和异常输出详细信息:

import java.lang.foreign.Arena;
import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.Linker;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SymbolLookup;
import java.lang.foreign.ValueLayout;
import java.lang.invoke.MethodHandle;
import java.util.Arrays;

// 434: Foreign Function & Memory API (Second Preview) // https://openjdk.org/jeps/434
class ForeignFunctionMemoryAPISecondPreview {
    private void radixsort() throws Throwable {

    // 1. Find foreign function on the C library path
    Linker linker          = Linker.nativeLinker();
    SymbolLookup stdlib    = linker.defaultLookup();
    MethodHandle radixsort = linker.downcallHandle(stdlib.find("radixsort").orElseThrow(), 
            FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.JAVA_CHAR));

    // 2. Allocate on-heap memory to store four strings
    String[] javaStrings = { "mouse", "cat", "dog", "car" };
        System.out.println("radixsort input: " + Arrays.toString(javaStrings));

    // 3. Use try-with-resources to manage the lifetime of off-heap memory
    try (Arena offHeap = Arena.openConfined()) {
            // 4. Allocate a region of off-heap memory to store four pointers
            MemorySegment pointers = offHeap.allocateArray(ValueLayout.ADDRESS, javaStrings.length);

            // 5. Copy the strings from on-heap to off-heap
            for (int i = 0; i < javaStrings.length; i++) {
                MemorySegment cString = offHeap.allocateUtf8String(javaStrings[i]);
                pointers.setAtIndex(ValueLayout.ADDRESS, i, cString);
            }

            // 6. Sort the off-heap data by calling the foreign function
            radixsort.invoke(pointers, javaStrings.length, MemorySegment.NULL, '\0');

            // 7. Copy the (reordered) strings from off-heap to on-heap
            for (int i = 0; i < javaStrings.length; i++) {
                MemorySegment cString = pointers.getAtIndex(ValueLayout.ADDRESS, i);
                // Java 21 Preview
        // cString = cString.reinterpret(Long.MAX_VALUE);
                // javaStrings[i] = cString.getUtf8String(0);
        System.out.println(cString);
            }
    }

    // 8. All off-heap memory is deallocated here
        System.out.println("radixsort output: " + Arrays.toString(javaStrings));
    }

    public static void main(String[] args) throws Throwable {
        System.out.println(String.format("Java Version: %s", System.getProperty("java.version")));

    var previewForeignFunctionMemoryAPISecond = new ForeignFunctionMemoryAPISecondPreview();
        previewForeignFunctionMemoryAPISecond.radixsort();
    }
}

// Output
/*
WARNING: Using incubator modules: jdk.incubator.vector, jdk.incubator.concurrent
Note: ForeignFunctionMemoryAPISecondPreview.java uses preview features of Java SE 20.
Note: Recompile with -Xlint:preview for details.
Java Version: 20.0.2
radixsort input: [mouse, cat, dog, car]
Exception in thread "main" java.lang.IndexOutOfBoundsException: Out of bound access on segment MemorySegment{ array: Optional.empty address:105553152688144 limit: 0 }; new offset = 0; new length = 1
    at java.base/jdk.internal.foreign.AbstractMemorySegmentImpl.outOfBoundException(AbstractMemorySegmentImpl.java:371)
    at java.base/jdk.internal.foreign.AbstractMemorySegmentImpl.apply(AbstractMemorySegmentImpl.java:357)
    at java.base/jdk.internal.foreign.AbstractMemorySegmentImpl.apply(AbstractMemorySegmentImpl.java:70)
    at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:98)
    at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:124)
    at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:448)
    at java.base/jdk.internal.foreign.AbstractMemorySegmentImpl.checkBounds(AbstractMemorySegmentImpl.java:346)
    at java.base/jdk.internal.foreign.AbstractMemorySegmentImpl.checkAccess(AbstractMemorySegmentImpl.java:311)
    at java.base/java.lang.invoke.VarHandleSegmentAsBytes.checkAddress(VarHandleSegmentAsBytes.java:81)
    at java.base/java.lang.invoke.VarHandleSegmentAsBytes.get(VarHandleSegmentAsBytes.java:108)
    at java.base/java.lang.foreign.MemorySegment.get(MemorySegment.java:1388)
    at java.base/jdk.internal.foreign.abi.SharedUtils.strlen(SharedUtils.java:199)
    at java.base/jdk.internal.foreign.abi.SharedUtils.toJavaStringInternal(SharedUtils.java:190)
    at java.base/java.lang.foreign.MemorySegment.getUtf8String(MemorySegment.java:890)
    at ForeignFunctionMemoryAPISecondPreview.radixsort(ForeignFunctionMemoryAPISecondPreview.java:43)
    at ForeignFunctionMemoryAPISecondPreview.main(ForeignFunctionMemoryAPISecondPreview.java:56)


  [1]: https://docs.oracle.com/en/java/javase/21/docs//api/java.base/java/lang/foreign/MemorySegment.html#reinterpret(long)

推荐答案

在Java 20中,您可以使用MemorySegment::ofAddress代替reinterpret:

cString = MemorySegment.ofAddress(cString.address(), Long.MAX_VALUE);

Java相关问答推荐

Java Streams在矩阵遍历中的性能影响

替换com. sun. jndi. dns. DnsContextFactory Wildfly23 JDK 17

JavaFX Maven Assembly插件一直打包到错误的JDK版本

是否在允许数组元素为空时阻止 idea 为空性警告?

无法了解Java线程所消耗的时间

如何从错误通道回复网关,使其不会挂起

Java流传输一个列表并创建单个对象

将响应转换为带值的键

Spring和可编辑";where";@Query

使用Jolt将字段转换为列表

未找到适用于响应类型[类java.io.InputStream]和内容类型[Text/CSV]的HttpMessageConverter

S,要对Java复制构造函数深度克隆所有属性进行单元测试,最可靠的方法是什么?

为什么有两种实现来检索数组类的组件类型?

在settings.gradle.kts和Build.gradle.kts中使用公共变量

如何配置空手道以使用FeignClient或RestTemplate代替ApacheHttpClient

Java递归泛型是否可以被视为继承和重写的语法糖

为什么Instant没有从UTC转换为PostgreSQL的时区?

设置背景时缺少Android编辑文本下划线

java中的网上购物车解析错误

在外部类和内部类之间,当调用外部类内部或外部的主方法时,它们的静态初始化程序的运行顺序不同