Почему FFM лучше JNI
Более безопасное взаимодействие с нативным кодом
«Почему FFM лучше JNI» — бесплатный урок Java Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.
Вызов нативного кода
Иногда Java требуется вызывать библиотеки на C или работать с памятью вне кучи. Классическим способом был интерфейс JNI для взаимодействия с нативным кодом (JNI). Современный способ — программный интерфейс внешних функций и памяти (FFM), окончательно утверждённый в Java 22 (JEP 454).
В этом уроке объясняется, почему FFM является лучшим выбором.
Что требовал JNI
JNI был неудобен:
- Писать связующий код на C с громоздкими сигнатурами
JNIEXPORT - Компилировать отдельную нативную динамическую библиотеку для каждой платформы
- Вручную преобразовывать типы Java и C
- Из-за ошибки легко обрушить JVM
FFM — только Java
FFM позволяет вызывать нативные функции и обращаться к нативной памяти целиком из Java. Не нужны связующий код на C, отдельный этап компиляции или написанное вручную преобразование данных.
Вы описываете сигнатуру нативной функции на Java и вызываете её через дескриптор метода.
Основные пакеты
Всё находится в java.lang.foreign. Основные типы:
LinkerиSymbolLookupдля поиска и привязки функцийMemorySegmentдля работы с нативной памятьюArenaдля детерминированного управления временем жизниMemoryLayoutиFunctionDescriptorдля описания структур
Безопасность благодаря продуманной конструкции
FFM гораздо безопаснее JNI:
- Доступ к памяти с проверкой границ
- Время жизни связано с
Arena, поэтому обращение к освобождённой памяти обнаруживается - Изоляция предотвращает небезопасный доступ из другого потока
Ошибки приводят к исключениям Java, а не к сбою VM.
Знакомство с API
Этот пример находит функцию C strlen и подготавливает дескриптор для её вызова. Суть в том, что это обычный код Java.
import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
public class Main {
public static void main(String[] args) {
Linker linker = Linker.nativeLinker();
SymbolLookup stdlib = linker.defaultLookup();
MethodHandle strlen = linker.downcallHandle(
stdlib.find("strlen").orElseThrow(),
FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS));
System.out.println("Bound a handle to strlen: " + strlen);
}
}Производительность
Вызовы нативного кода через FFM сопоставимы по производительности с JNI и часто работают быстрее, поскольку JIT может встраивать и оптимизировать сгенерированные заглушки. При каждом вызове не требуется проходить через промежуточный переход на стороне C.
Включение доступа к нативному коду
Поскольку нативный код может быть опасен, FFM может выдавать предупреждение или требовать явного разрешения. Вы предоставляете доступ при запуске с помощью --enable-native-access=ALL-UNNAMED (или имени конкретного модуля), чтобы отключить предупреждения.
Замена sun.misc.Unsafe
FFM (вместе с API управления памятью) также является официальной заменой давно устаревших операций с памятью вне кучи из sun.misc.Unsafe. Библиотеки, которые вручную управляли нативными буферами, могут перейти на безопасные поддерживаемые API.
Инструменты: jextract
Для больших библиотек C сопутствующий инструмент jextract читает файл заголовка C и автоматически генерирует привязки FFM для Java. Вам не нужно писать дескрипторы вручную.
Это средство повышения производительности разработки для FFM, подобное генератору кода.
Когда использовать FFM
Используйте FFM, когда вам необходимо:
- Вызвать существующую библиотеку C/C++
- Взаимодействовать с OS на низком уровне
- Эффективно управлять большими буферами вне кучи
Для задач, полностью написанных на Java, он не нужен.
Быстрая проверка
Вспомните главное преимущество перед JNI.
Итоги
Вы узнали, почему FFM лучше JNI:
- Чистый Java-код, без связующего кода на C и дополнительной компиляции
- Безопасность: проверка границ, время жизни Arena, изоляция
- Сопоставимая или более высокая производительность
- Заменяет
sun.misc.Unsafeи работает вместе сjextract
Далее: управление нативной памятью с помощью MemorySegment и Arena.
Часто задаваемые вопросы
Урок «Почему FFM лучше JNI» бесплатный?
Да — полный текст урока «Почему FFM лучше JNI» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.
Чему я научусь в уроке «Почему FFM лучше JNI»?
Более безопасное взаимодействие с нативным кодом Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Java Academy?
Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Почему FFM лучше JNI»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Java Academy?
Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Почему FFM лучше JNI
- MemorySegment и Arena
- Дескрипторы вызовов downcall
- Макеты и структуры