Spec-Zone.ru › OpenJDK 24

Пакет java.lang.foreign

package java.lang.foreign

Предоставляет низкоуровневый доступ к памяти и функциям за пределами среды выполнения Java.

Доступ к внешней памяти

Основной абстракцией для поддержки доступа к внешней памяти является MemorySegment, моделирующая непрерывный участок памяти, находящийся как внутри, так и вне кучи Java. Отрезки памяти обычно выделяются с помощью Arena, который контролирует срок жизни участков памяти, на которых базируются выделяемые им отрезки. Содержание отрезка памяти может быть описано с помощью memory layout, который предоставляет базовые операции для запроса размеров, смещений и ограничений выравнивания. Схемы памяти также предоставляют альтернативный, более абстрактный способ доступа к отрезкам памяти, используя обращение к отрезкам памяти с помощью обработчиков переменных, которые можно вычислить, используя пути схемы.

Например, для выделения внекучевого участка памяти, достаточного для хранения 10 значений примитивного типа int, и заполнения его значениями от 0 до 9, можно использовать следующий код:

try (Arena arena = Arena.ofConfined()) {
    MemorySegment segment = arena.allocate(10 * 4);
    for (int i = 0 ; i < 10 ; i++) {
        segment.setAtIndex(ValueLayout.JAVA_INT, i, i);
    }
}
Этот код создаёт нативный отрезок памяти, то есть отрезок памяти, поддерживаемый внекучевой памятью; размер отрезка составляет 40 байт, достаточно для хранения 10 значений примитивного типа int. Нативный отрезок выделяется с помощью ограниченной области. Таким образом, доступ к нативному отрезку ограничен текущей нитью (нитью, создавшей область). Кроме того, при закрытии области нативный отрезок становится недействительным, а поддерживающая его область памяти освобождается. Обратите внимание на использование конструкции try-with-resources: этот идиом гарантирует, что внекучевой участок памяти, поддерживающий нативный отрезок, будет освобождён в конце блока в соответствии с семантикой, описанной в разделе 14.20.3 спецификации языка Java.

Отрезки памяти обеспечивают строгие гарантии безопасности при обращении к памяти. Во-первых, при доступе к отрезку памяти координаты доступа проверяются (при доступе), чтобы убедиться, что доступ не происходит по любому адресу, который находится вне границ отрезка памяти, используемого операцией доступа. Мы называем эту гарантию пространственной безопасностью; другими словами, доступ к отрезкам памяти проверяется на границах, аналогично доступу к массивам, как описано в разделе 15.10.4 спецификации языка Java.

Кроме того, для предотвращения доступа к области памяти после её освобождения (т.е. использования после освобождения), отрезок также проверяется (при доступе), чтобы убедиться, что область, из которой он был получен, не была закрыта. Мы называем эту гарантию временной безопасностью.

Вместе пространственная и временная безопасность гарантируют, что каждая операция доступа к памяти либо выполняется успешно - и обращается к допустимому расположению в области памяти, поддерживающей отрезок памяти - либо терпит неудачу.

Доступ к внешним функциям

Ключевыми абстракциями для поддержки доступа к внешним функциям являются SymbolLookup, FunctionDescriptor и Linker. Первый используется для поиска символов внутри библиотек; второй используется для моделирования сигнатуры внешних функций, а третий используется для связывания внешних функций в качестве MethodHandle экземпляров, чтобы клиенты могли выполнять вызовы внешних функций непосредственно в Java, без необходимости промежуточных слоёв кода C/C++ (как в случае с Java Native Interface (JNI)).

Например, для вычисления длины строки с использованием функции стандартной библиотеки C strlen на платформе Linux/x64 можно использовать следующий код:

 Linker linker = Linker.nativeLinker();
 SymbolLookup stdlib = linker.defaultLookup();
 MethodHandle strlen = linker.downcallHandle(
     stdlib.findOrThrow("strlen"),
     FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS)
 );

 try (Arena arena = Arena.ofConfined()) {
     MemorySegment cString = arena.allocateFrom("Hello");
     long len = (long)strlen.invokeExact(cString); // 5
 }
Здесь мы получаем нативный линкер и используем его для поиска функции strlen в стандартной библиотеке C; обратный вызов обработать метод, нацеленный на эту функцию, впоследствии получаетсяОГРАНИЧЕННЫЙ. Для успешного завершения связи необходимо предоставить экземпляр FunctionDescriptor, описывающий подпись функции strlen. На основе этой информации линкер однозначно определит последовательность шагов, которые превратят вызов обработчика метода (здесь выполняемый с помощью MethodHandle.invokeExact(java.lang.Object...)) в вызов внешней функции в соответствии с правилами, заданными ABI используемой платформы.

Класс Arena также предоставляет множество полезных методов для взаимодействия с внешним кодом, таких как преобразование строк Java в нультерминированные строки UTF-8, как показано в приведённом выше примере.

Примечание API:
Обычные гарантии модели памяти (см. 17.4) не применяются при доступе к нативным отрезкам памяти, так как эти отрезки поддерживаются внекучевыми областями памяти.
С:
22
Внешние спецификации
  • Спецификация Java Native Interface
Пакет Описание
java.lang
Предоставляет классы, фундаментальные для разработки на языке программирования Java.
Класс Описание
AddressLayout
Макет значения, используемый для моделирования адреса некоторого региона памяти.
Arena
Арена управляет жизненным циклом сегментов нативной памяти, обеспечивая гибкое выделение и своевременное освобождение.
FunctionDescriptor
Описание функции моделирует сигнатуру внешней функции.
GroupLayout
Составной макет, являющийся агрегацией нескольких разнородных элементов макета.
Linker
Линкер предоставляет доступ к внешним функциям из кода Java и доступ к коду Java из внешних функций.
Linker.Option
Параметр линкера используется для предоставления дополнительных параметров запросу связи.
MemoryLayout
Макет памяти описывает содержимое сегмента памяти.
MemoryLayout.PathElement
Элемент в пути макета.
MemorySegment
Сегмент памяти предоставляет доступ к смежному региону памяти.
MemorySegment.Scope
Область моделирует жизненный цикл всех сегментов памяти, связанных с ней.
PaddingLayout
Макет заполнения.
SegmentAllocator
Объект, который может использоваться для выделения сегментов памяти.
SequenceLayout
Составной макет, обозначающий однородное повторение заданного элемента макета.
StructLayout
Макет группы, члены которого расположены последовательно.
SymbolLookup
Поиск символа получает адрес символа в одной или нескольких библиотеках.
UnionLayout
Макет группы, члены которой расположены в одном и том же начальном смещении.
ValueLayout
Макет, моделирующий значения основных типов данных.
ValueLayout.OfBoolean
Макет значения, носитель которого — boolean.class.
ValueLayout.OfByte
Макет значения, носитель которого — byte.class.
ValueLayout.OfChar
Макет значения, носитель которого — char.class.
ValueLayout.OfDouble
Макет значения, носитель которого — double.class.
ValueLayout.OfFloat
Макет значения, носитель которого — float.class.
ValueLayout.OfInt
Макет значения, носитель которого — int.class.
ValueLayout.OfLong
Макет значения, носитель которого — long.class.
ValueLayout.OfShort
Макет значения, носитель которого — short.class.

© 1993, 2025, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://download.java.net/java/early_access/jdk24/docs/api/java.base/java/lang/foreign/package-summary.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API