После шести месяцев разработки компания Oracle опубликовала платформу Java SE 24 (Java Platform, Standard Edition 24), в качестве эталонной реализации которой используется открытый проект OpenJDK. За исключением удаления некоторых устаревших возможностей в Java SE 24 сохранена обратная совместимость с прошлыми выпусками платформы Java - большинство ранее написанных Java-проектов без изменений будут работоспособны при запуске под управлением новой версии. Готовые для установки сборки Java SE 24 (JDK, JRE и Server JRE) подготовлены для Linux (x86_64, AArch64), Windows (x86_64) и macOS (x86_64, AArch64). Разработанная в рамках проекта OpenJDK эталонная реализация Java SE 24 полностью открыта под лицензией GPLv2 с исключениями GNU ClassPath, разрешающими динамическое связывание с коммерческими продуктами.
Java SE 24 отнесен к категории выпусков с обычным сроком поддержки, обновления для которого будут выпускаться до следующего релиза. В качестве ветки с длительным сроком поддержки (LTS) следует использовать Java SE 21 или Java SE 17, обновления для которых будут выпускаться до 2031 и 2029 годов соответственно (общедоступные - до 2028 и 2026 годов). Расширенная поддержка LTS-ветки Java SE 8 продлится до 2030 года, а Java SE 11 - до 2032 года. Следующим LTS-релизом станет осенний выпуск Java SE 25.
Среди предложенных в Java SE 24 новшеств:
- Предложен экспериментальный генеративный режим работы сборщика мусора Shenandoah, при котором раздельно обрабатываются старые и недавно созданные объекты для повышения эффективности очистки объектов с небольшим временем жизни. Новый режим обеспечивает более предсказуемую пропускную способность, устойчивость к изменению нагрузки и снижение потребления памяти при сборке мусора. Планировщик Shenandoah нацелен на сокращение времени остановок во время сборки мусора за счет проведения большего объема работ параллельно с выполнением Java-приложений.
- В HotSpot JVM реализована экспериментальная поддержка компактных заголовков объектов, размер которых на 64-разрядных системах уменьшен с 96 до 64 бит (с 12 до 8 байт). Уменьшение размера заголовков позволяет сократить размер кучи и повысить эффективность работы кэша.
- В сборщике мусора G1 упрощена реализация барьеров, отслеживающих доступ приложения к памяти. В новой версии операции расширения барьеров перенесены на более поздний этап компиляции в C2 JIT. Проведенные тесты показывают, что подобный перенос позволяет снизить накладные расходы в JIT-компиляторе C2 на 10-20% в зависимости от приложения.
- Добавлен API для использования криптографических функций формирования ключа (KDF, key derivation function), позволяющих сформировать дополнительные ключи необходимой длины на основе секретного ключа (например, пароля) и произвольного набора данных. KDF API пока имеет статус предварительного (preview).
- Добавлена возможность упреждающей (Ahead-of-Time) загрузки и компоновки классов. Изменение позволяет ускорить запуск HotSpot JVM за счет предоставления используемых в приложении классов в уже загруженном и скомпонованном состоянии. Во время первого запуска приложения состояние всех классов сбрасывается в кэш и при последующих запусках используется для ускорения загрузки.
ClassFile cf = ClassFile.of();
ClassModel classModel = cf.parse(bytes);
byte[] newBytes = cf.build(classModel.thisClass().asSymbol(),
classBuilder -> {
for (ClassElement ce : classModel) {
if (!(ce instanceof MethodModel mm
&& mm.methodName().stringValue().startsWith("debug"))) {
classBuilder.with(ce);
}
}
});
Добавлен расширенный API Stream, поддерживающий определение собственных промежуточных операций, которые могут оказаться полезны в случаях, когда существующих встроенных промежуточных операций недостаточно для желаемого преобразования данных. Собственные обработчики подключаются при помощи новой промежуточной операции Stream::gather(Gatherer), которая обрабатывает элементы потока, применяя к ним заданный пользователем обработчик.
jshell> Stream.of(1,2,3,4,5,6,7,8,9).gather(new WindowFixed(3)).toList()
$1 ==> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
- Предложена четвертая предварительная реализация ограниченных значений (Scoped Values), позволяющих совместно использовать неизменяемые данные в потоках и эффективно обмениваться данными между дочерними потоками (значения наследуются). Scoped Values развиваются для замены механизма переменных локальных к потоку (thread-local variables) и более эффективны при использовании очень большого числа виртуальных потоков (тысячи и миллионы потоков). Главное отличие Scoped Values от переменных локальных к потоку в том, что первые записываются один раз, в дальнейшем не могут быть изменены и остаются доступны только на время выполнения потока.
- В механизмы сопоставления с образцом добавлена предварительная поддержка использования примитивных типов (int, byte, char и другие базовые типы, не являющиеся объектами) во всех видах шаблонов, в операторе "instanceof" и в блоках "switch".
switch (x.getStatus()) {
case 0 -> "okay";
case 1 -> "warning";
case 2 -> "error";
case int i -> "unknown status: " + i;
}
if (i instanceof byte b) {
... b ...
}
- Предложена девятая предварительная реализация API Vector, предоставляющего функции для векторных вычислений, которые выполняются с использованием векторных инструкций процессоров x86_64 и AArch64 и позволяют одновременно применить операции сразу к нескольким значениям (SIMD). В отличие от предоставляемых в JIT-компиляторе HotSpot возможностей по автовекторизации скалярных операций, новый API даёт возможность явно управлять векторизацией для параллельной обработки данных.
- Реализована поддержка синхронизации виртуальных потоков без их прикрепления (pinning) к потокам, связанным с платформой. Виртуальные потоки в синхронизированном методе или выражении в состоянии блокировки теперь освобождают свой платформенный поток, позволяя другим виртуальным потокам использовать его, что значительно увеличивает количество доступных виртуальных потоков и улучшает масштабируемость приложений, использующих многопоточность.
- Добавлен третий предварительный вариант возможности, разрешающей указание в конструкторах выражений перед вызовом super(...), используемого для явного вызова конструктора родительского класса из конструктора наследуемого класса, если эти выражения не ссылаются на создаваемый конструктором экземпляр.
class Outer {
void hello() {
System.out.println("Hello");
}
class Inner {
Inner() {
hello();
super();
}
}
}
- В утилите jlink реализована поддержка создания образов run-time без использования файлов JMOD, что позволяет примерно на 25% сократить размер JDK.
- Добавлен второй предварительный вариант использования одного выражения "import module M" для импорта сразу всех пакетов, экспортируемых указанным модулем. Изменение существенно упрощает повторное использование модульных библиотек, позволяя подключать библиотеки и классы без определения их места в иерархии пакетов. Например, указание "import module java.base" приведёт к импорту всех 54 пакетов, входящих в модуль java.base, которые ранее потребовалось бы упоминать по-отдельности ("import java.io.*", "import java.util.*" и т.п.).
- Добавлена четвёртая предварительная реализация неявно объявленных классов и безымянных экземпляров метода "main", в которых можно обойтись без объявлений public/static, передачи массива аргументов и прочих сущностей, связанных с объявлением класса.
// было
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
// теперь можно
void main() {
System.out.println("Hello, World!");
}
- Предложен для тестирования четвертый предварительный вариант API для cтруктурированного параллелизма (Structured Concurrency), упрощающего разработку многопоточных приложений за счет обработки нескольких задач, выполняемых в разных потоках, как единого блока.
- В API KeyPairGenerator, Signature и KeyFactory добавлена поддержка алгоритмов ML-KEM (CRYSTALS-Kyber) и ML-DSA (CRYSTALS-Dilithium), стандартизированных Национальным институтом стандартов и технологий США (NIST) и стойких к подбору на квантовом компьютере. Данные алгоритмы используют методы криптографии, основанные на решении задач теории решеток, время решения которых не отличается на обычных и квантовых компьютерах.
- В сборщике мусора ZGC удалена поддержка не генеративного режима работы, не разделяющего обработку "старых" и "молодых" объектов. Начиная с Java SE 23 генеративный режим ZGC применяется по умолчанию.
- Добавлен вывод предупреждений об использовании API JNI (Java Native Interface) и FFM (Foreign Function & Memory) с целью подготовки разработчиков к ограничению доступа к данным API из-за включения в одном из будущих выпусков режима обеспечения целостности, по умолчанию запрещающего взаимодействие с нативным кодом.
- Включен вывод предупреждения при использовании методов доступа к внешней памяти (вне JVM), предоставляемых классом sun.misc.Unsafe. Для обращения к памяти вне кучи (off-heap) и взаимодействия с внешними кодом рекомендуется использовать API VarHandle. В прошлом выпуске поддержка sun.misc.Unsafe была объявлена устаревшей.
- Отключен Security Manager, который давно потерял актуальность и оказался невостребованным после прекращения поддержки браузерного плагина. Security Manager был переведен в разряд устаревших в Java 17. В одном из следующих выпусков планируется полностью удалить код Security Manager.
- Удален код для поддержки 32-разрядной платформы ОС Windows на системах x86. Объявлен устаревшим и запланирован к удалению порт Java для 32-разрядных систем x86 (будет прекращена поддержка Linux на 32-разрядных системах x86).
Дополнительно можно отметить публикацию обновления платформы для создания приложений с графическим интерфейсом JavaFX 24 и новый выпуск универсальной виртуальной машины GraalVM, поддерживающей запуск приложений на JavaScript (Node.js), Python, Ruby, R, любых языках для JVM (Java, Scala, Clojure, Kotlin) и языках, для которых может формироваться биткод LLVM (C, C++, Rust). Кроме поддержки JDK 24 в новой версии GraalVM проведены оптимизации для задач, связанных с машинным обучением, улучшена поддержка компиляции Java-байткода в машинный код, добавлен механизм SkipFlow для сокращения размера исполняемых файлов и уменьшения времени компиляции.