Пакет 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);
}
}
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
- Внешние спецификации
| Класс | Описание |
|---|---|
| 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