Как сохранить объект-массив в собственной памяти с помощью Java Panama

Я хочу реализовать структуру данных в собственной памяти с помощью API доступа к внешней памяти Project Panama.

Для этого мне нужен базовый массив объектов ( 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 (например, Object)? И если это так, как я могу разыменовать этот MemorySegment с помощью VarHandle, если VarHandles поддерживает только примитивные носители?

1 ответ

Решение

Есть ли способ хранить непримитивы в MemorySegment (например, Object)?

Короче нет. Объектами управляет среда выполнения Java, и они не могут быть безопасно сохранены в собственной памяти (например, потому что сборщик мусора не сможет отслеживать ссылки на объекты внутри объектов в собственной памяти).

Однако, как отмечено в комментариях, для ваших целей может быть достаточно хранить данные внутри объекта в собственной памяти. Например, если объект содержит только примитивные поля (хотя то же самое можно было бы сделать рекурсивно для полей объекта), можно было бы записать каждое такое поле отдельно в собственную память. Например (с API JDK 16):

      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());
    }
}
Другие вопросы по тегам