0Pricing
Java Academy · Урок

Почему 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 — локальная установка не требуется.

Все уроки этого курса

  1. Почему FFM лучше JNI
  2. MemorySegment и Arena
  3. Дескрипторы вызовов downcall
  4. Макеты и структуры
← Назад к Java Academy