java - 如何使用 Java Panama 在 native 内存中存储对象数组

标签 java buffer project-panama

我想使用巴拿马项目的外部内存访问 API 在 native 内存中实现数据结构。

为此,我需要一个用于条目的底层对象数组 (Object[])。

在外部内存访问 API 的所有示例中,MemorySegments 仅用于存储和检索原语,如下所示:

//I would like to use Object here instead of int
ResourceScope scope = ResourceScope.newConfinedScope();
SequenceLayout layout = MemoryLayout.sequenceLayout(100, MemoryLayouts.JAVA_INT); 
VarHandle intHandle = seq.varHandle(int.class, sequenceElement());
MemorySegment segment = MemorySegment.allocateNative(layout, scope);

有没有办法将非基元存储在 MemorySegment(例如对象)中? 如果是这种情况,当 VarHandle 仅支持原始载体时,我如何使用 VarHandle 取消引用该 MemorySegment?

最佳答案

Is there a way to store non primitives in a MemorySegment (e.g. Object)?

不,至少不是直接的。对象由 Java 运行时管理,它们不能安全地存储在 native 内存中(例如,因为垃圾收集器无法跟踪 native 内存中对象内部的对象引用)。​​

但是,如评论中所述,出于您的目的,将数据存储在 native 内存中的对象内可能就足够了。例如,如果一个对象只包含原始字段(尽管可以对对象字段递归执行相同的操作),则可以将每个此类字段分别写入 native 内存。例如(使用 JDK 16 API):

public static void main(String[] args) {
    try (MemorySegment segment = MemorySegment.allocateNative(Widget.NATIVE_LAYOUT)) {
        Widget widget1 = new Widget(1, 2);
        widget1.write(segment);

        Widget widget2 = Widget.read(segment);
        System.out.println(widget2); // Widget[x=1, y=2]
    }
}

record Widget(int x, int y) {
    static final MemoryLayout NATIVE_LAYOUT = MemoryLayout.ofStruct(
        MemoryLayouts.JAVA_INT.withName("x"),
        MemoryLayouts.JAVA_INT.withName("y")
    );

    static final VarHandle VH_x = NATIVE_LAYOUT.varHandle(int.class, MemoryLayout.PathElement.groupElement("x"));
    static final VarHandle VH_y = NATIVE_LAYOUT.varHandle(int.class, MemoryLayout.PathElement.groupElement("y"));

    public static Widget read(MemorySegment segment) {
        int x = (int) VH_x.get(segment);
        int y = (int) VH_y.get(segment);
        return new Widget(x, y);
    }

    public void write(MemorySegment segment) {
        VH_x.set(segment, x());
        VH_y.set(segment, y());
    }
}

关于java - 如何使用 Java Panama 在 native 内存中存储对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67943155/

相关文章:

java - IntelliJ IDEA 12 重复类 R.java 和 BuildConfig.java

java - org.openqa.selenium.WebDriverException : Session [xyz] was terminated due to ORPHAN error using Zalenium

go - 缓冲阅读器 VS listenUDP

Java:ByteBuffer 与 jdk.incubator.foreign(巴拿马)外部内存方法(MemoryLayout/Segment)的性能对比

Java 10 巴拿马项目 - 将 JNI 解决方案移植到巴拿马

java - 为什么我损坏的缓冲区以 8x8 像素的 block 出现?

java - Gradle项目共享人工插件依赖

Java VarHandle 到带有 java.lang.foreign API 的 C 字符串

javascript - 将缓冲区对象转换为图像

node.js - 如何从 Buffer.from 获得与 fs.readFile 相同的输出?