🌉 Project Panama. Как вызвать C/C++ без боли?
Java долгое время жила в изоляции. Чтобы выйти за пределы JVM (вызвать функцию из OS, использовать библиотеку ML на C++ или графику на Rust), нам приходилось писать "клей" (glue code) на C.
Project Panama (Foreign Function & Memory API) меняет парадигму. Теперь Java умеет говорить с нативным кодом напрямую.
🗑 Что мы выбрасываем (JNI)
1. Больше не нужно писать ни строчки на C/C++.
2. Больше нет утилиты
3. Больше нет риска, что
✨ Как это работает (FFM API)
Допустим, мы хотим вызвать стандартную функцию
Шаг 1. Находим библиотеку
Шаг 2. Описываем сигнатуру (Descriptor)
Мы говорим Java: "Эта функция принимает указатель (Адрес) и возвращает число (long)".
Шаг 3. Выделяем память и вызываем
Самое интересное: мы аллоцируем память вне Java кучи (Off-heap) безопасным способом через
🤖 Killer Feature:
Вы скажете: "Писать дескрипторы для каждой функции вручную? Это же муторно!"
И вы правы. Поэтому есть утилита jextract.
Вы просто "скармливаете" ей заголовочный файл
Она сама сгенерирует все Java-классы и методы. Вы просто пишете:
Это выглядит и работает как обычный Java-код, но под капотом вызывает OpenGL напрямую.
🧠 Зачем это нужно?
1. AI и ML: TensorFlow, PyTorch, OpenCV - все они написаны на C++. Теперь Java может использовать их без тормозов JNI.
2. Базы данных: Драйверы могут работать напрямую с сетевым стеком OS (io_uring).
3. Rust: Вы можете написать критически важную логику на Rust, скомпилировать в библиотеку и использовать в Java.
🏆 Итог серии Modern Java
• Она запускается мгновенно (GraalVM).
• Она держит миллионы соединений (Virtual Threads).
• Она безопасна и лаконична (Records, Sealed Classes).
• Она открыта миру (Panama).
#ProjectPanama #FFM #Native #Performance
👉 @java_geek
Java долгое время жила в изоляции. Чтобы выйти за пределы JVM (вызвать функцию из OS, использовать библиотеку ML на C++ или графику на Rust), нам приходилось писать "клей" (glue code) на C.
Project Panama (Foreign Function & Memory API) меняет парадигму. Теперь Java умеет говорить с нативным кодом напрямую.
🗑 Что мы выбрасываем (JNI)
1. Больше не нужно писать ни строчки на C/C++.
2. Больше нет утилиты
javah.3. Больше нет риска, что
Unsafe удалят и ваш код сломается.✨ Как это работает (FFM API)
Допустим, мы хотим вызвать стандартную функцию
strlen из библиотеки C, чтобы узнать длину строки.Шаг 1. Находим библиотеку
Linker linker = Linker.nativeLinker();
SymbolLookup stdlib = linker.defaultLookup();
// Ищем адрес функции "strlen" в памяти процесса
MemorySegment strlenAddress = stdlib.find("strlen").orElseThrow();
Шаг 2. Описываем сигнатуру (Descriptor)
Мы говорим Java: "Эта функция принимает указатель (Адрес) и возвращает число (long)".
FunctionDescriptor descriptor = FunctionDescriptor.of(
ValueLayout.JAVA_LONG, // Возвращаемое значение
ValueLayout.ADDRESS // Аргумент (указатель на строку)
);
MethodHandle strlen = linker.downcallHandle(strlenAddress, descriptor);
Шаг 3. Выделяем память и вызываем
Самое интересное: мы аллоцируем память вне Java кучи (Off-heap) безопасным способом через
Arena.
try (Arena arena = Arena.ofConfined()) {
// Превращаем Java String в C-строку (char*)
MemorySegment cString = arena.allocateFrom("Hello Panama!");
// Вызываем функцию C прямо из Java!
long length = (long) strlen.invoke(cString);
System.out.println(length); // 13
}
// Тут память автоматически очищается (как free() в C)
🤖 Killer Feature:
jextractВы скажете: "Писать дескрипторы для каждой функции вручную? Это же муторно!"
И вы правы. Поэтому есть утилита jextract.
Вы просто "скармливаете" ей заголовочный файл
.h:
jextract --output src -t org.example.opengl /usr/include/GL/gl.h
Она сама сгенерирует все Java-классы и методы. Вы просто пишете:
gl.glClear(gl.GL_COLOR_BUFFER_BIT());
Это выглядит и работает как обычный Java-код, но под капотом вызывает OpenGL напрямую.
🧠 Зачем это нужно?
1. AI и ML: TensorFlow, PyTorch, OpenCV - все они написаны на C++. Теперь Java может использовать их без тормозов JNI.
2. Базы данных: Драйверы могут работать напрямую с сетевым стеком OS (io_uring).
3. Rust: Вы можете написать критически важную логику на Rust, скомпилировать в библиотеку и использовать в Java.
🏆 Итог серии Modern Java
• Она запускается мгновенно (GraalVM).
• Она держит миллионы соединений (Virtual Threads).
• Она безопасна и лаконична (Records, Sealed Classes).
• Она открыта миру (Panama).
#ProjectPanama #FFM #Native #Performance
👉 @java_geek
👍4❤1🤯1
🗑️ Java Garbage Collector: Кто убирает за вами мусор?
Разработчики на C и C++ живут в постоянном страхе утечек памяти: выделил память через
Всю грязную работу делает Garbage Collector (Сборщик мусора или просто GC). Но если не понимать, как он работает, ваше приложение однажды просто "зависнет" на пару секунд на продакшене.
🛑 Главная проблема: Stop-The-World
GC не может убирать мусор, пока ваше приложение активно меняет ссылки на объекты. Ему нужно поставить всё на паузу. Эта пауза называется Stop-The-World (STW).
В этот момент все ваши потоки замирают, пользователи видят "колесико загрузки", а запросы по сети отваливаются по таймауту. Вся эволюция GC в Java - это борьба за уменьшение этих пауз.
🧬 Гипотеза поколений
Как GC понимает, что удалять? Он опирается на одно гениальное наблюдение: 98% объектов умирают молодыми. (Например, локальные переменные внутри метода живут доли секунды).
Поэтому память (Heap) поделили на две части:
1. Young Generation (Молодое поколение): Сюда попадают все новые объекты. Очистка здесь происходит часто и невероятно быстро (Minor GC).
2. Old Generation (Старое поколение): Сюда "переезжают" объекты-долгожители (например, закэшированные данные или синглтоны Spring). Очистка здесь происходит редко, но занимает много времени (Major/Full GC).
🥊 Битва титанов: Какой GC выбрать?
В современных версиях Java вам, как правило, нужно знать о двух главных сборщиках.
1. G1 (Garbage-First)
• Статус: Включен по умолчанию с Java 9.
• Как работает: Дробит память на сотни мелких регионов. Во время уборки он смотрит: "Ага, вот в этом регионе 90% мусора, начну с него" (отсюда и название - мусор в первую очередь).
• Кому подходит: 95% обычных веб-приложений. Он отлично балансирует между высокой пропускной способностью и приемлемыми паузами (целевая пауза по умолчанию — 200 мс).
2. ZGC (Z Garbage Collector)
• Статус: Готов к бою (Production Ready) с Java 15, а в Java 21 стал генерационным.
• Как работает: Настоящая магия и инженерное чудо. ZGC выполняет почти всю работу параллельно с вашим приложением, используя "цветные указатели" (colored pointers).
• Суперсила: Паузы Stop-The-World не превышают 1 миллисекунды, даже если у вас куча (Heap) размером в 16 Терабайт!
• Кому подходит: Финансовым биржам, игровым серверам и системам, где важна ультра-низкая задержка (Low Latency).
🛠 Как включить?
Ничего устанавливать не нужно, просто добавьте флаг при запуске
• Для G1 (если у вас старая Java):
• Для ZGC:
🧠 Золотое правило Memory Management
Сборщик мусора в Java невероятно умен. Не пытайтесь ему "помогать".
Вызовы
#Java #GarbageCollector #Performance #JVM #Backend
👉 @java_geek
Разработчики на C и C++ живут в постоянном страхе утечек памяти: выделил память через
malloc - обязан очистить через free. Мы же в Java просто пишем new Object() и идем пить кофе. Всю грязную работу делает Garbage Collector (Сборщик мусора или просто GC). Но если не понимать, как он работает, ваше приложение однажды просто "зависнет" на пару секунд на продакшене.
🛑 Главная проблема: Stop-The-World
GC не может убирать мусор, пока ваше приложение активно меняет ссылки на объекты. Ему нужно поставить всё на паузу. Эта пауза называется Stop-The-World (STW).
В этот момент все ваши потоки замирают, пользователи видят "колесико загрузки", а запросы по сети отваливаются по таймауту. Вся эволюция GC в Java - это борьба за уменьшение этих пауз.
🧬 Гипотеза поколений
Как GC понимает, что удалять? Он опирается на одно гениальное наблюдение: 98% объектов умирают молодыми. (Например, локальные переменные внутри метода живут доли секунды).
Поэтому память (Heap) поделили на две части:
1. Young Generation (Молодое поколение): Сюда попадают все новые объекты. Очистка здесь происходит часто и невероятно быстро (Minor GC).
2. Old Generation (Старое поколение): Сюда "переезжают" объекты-долгожители (например, закэшированные данные или синглтоны Spring). Очистка здесь происходит редко, но занимает много времени (Major/Full GC).
🥊 Битва титанов: Какой GC выбрать?
В современных версиях Java вам, как правило, нужно знать о двух главных сборщиках.
1. G1 (Garbage-First)
• Статус: Включен по умолчанию с Java 9.
• Как работает: Дробит память на сотни мелких регионов. Во время уборки он смотрит: "Ага, вот в этом регионе 90% мусора, начну с него" (отсюда и название - мусор в первую очередь).
• Кому подходит: 95% обычных веб-приложений. Он отлично балансирует между высокой пропускной способностью и приемлемыми паузами (целевая пауза по умолчанию — 200 мс).
2. ZGC (Z Garbage Collector)
• Статус: Готов к бою (Production Ready) с Java 15, а в Java 21 стал генерационным.
• Как работает: Настоящая магия и инженерное чудо. ZGC выполняет почти всю работу параллельно с вашим приложением, используя "цветные указатели" (colored pointers).
• Суперсила: Паузы Stop-The-World не превышают 1 миллисекунды, даже если у вас куча (Heap) размером в 16 Терабайт!
• Кому подходит: Финансовым биржам, игровым серверам и системам, где важна ультра-низкая задержка (Low Latency).
🛠 Как включить?
Ничего устанавливать не нужно, просто добавьте флаг при запуске
java -jar:• Для G1 (если у вас старая Java):
-XX:+UseG1GC• Для ZGC:
-XX:+UseZGC🧠 Золотое правило Memory Management
Сборщик мусора в Java невероятно умен. Не пытайтесь ему "помогать".
Вызовы
System.gc() в коде - это выстрел себе в ногу. Просто пишите чистый код, не держите ссылки на объекты, которые вам больше не нужны, и GC сделает всё сам.#Java #GarbageCollector #Performance #JVM #Backend
👉 @java_geek
👍4❤1