Выпуск Java SE 25 LTS и OpenJDK 25

После шести месяцев разработки компания Oracle опубликовала платформу Java SE 25 (Java Platform, Standard Edition 24), в качестве эталонной реализации которой используется открытый проект OpenJDK. За исключением удаления некоторых устаревших возможностей в Java SE 25 сохранена обратная совместимость с прошлыми выпусками платформы Java — большинство ранее написанных Java-проектов без изменений будут работоспособны при запуске под управлением новой версии. Готовые для установки сборки Java SE 25 (JDK, JRE и Server JRE) подготовлены для Linux (x86_64, AArch64), Windows (x86_64) и macOS (x86_64, AArch64). Разработанная в рамках проекта OpenJDK эталонная реализация Java SE 25 полностью открыта под лицензией GPLv2 с исключениями GNU ClassPath, разрешающими динамическое связывание с коммерческими продуктами.

Java SE 25 отнесён к выпускам с расширенным сроком поддержки, обновления для которого будут выпускаться до 2033 года (общедоступные обновления будут выходить до сентября 2030 года). В качестве ветки с длительным сроком поддержки (LTS) также продолжают сопровождаться ветки Java SE 17 и 21, обновления для которой будут выпускаться до 2029 и 2031 годов, соответственно (общедоступные — до 2026 и 2028 годов). Расширенная поддержка LTS-веток Java SE 8 и 11 продлится до 2030 и 2032 годов.

Среди предложенных в Java SE 25 новшеств (1, 2, 3, 4):

  • Предложен компактный вариант оформления программ, который может оказаться полезным для обучения и при разработке небольших приложений. В компактной форме не требуется определение лишних классов, автоматически импортируются типовые API и доступны упрощённые методы ввода/вывода. Например, приложение «Hello, World!» можно свести к:
    
       void main() {
           IO.println("Hello, World!");
       }
    
  • Добавлена возможность использования одного выражения «import module M» для импорта сразу всех пакетов, экспортируемых указанным модулем. Изменение существенно упрощает повторное использование модульных библиотек, позволяя подключать библиотеки и классы без определения их места в иерархии пакетов. Например, указание «import module java.base» приведёт к импорту всех 54 пакетов, входящих в модуль java.base, которые ранее потребовалось бы упоминать по-отдельности («import java.io.*», «import java.util.*» и т.п.).
  • Добавлен генеративный режим работы сборщика мусора Shenandoah, при котором раздельно обрабатываются старые и недавно созданные объекты для повышения эффективности очистки объектов с небольшим временем жизни. Новый режим обеспечивает более предсказуемую пропускную способность, устойчивость к изменению нагрузки и снижение потребления памяти при сборке мусора. Планировщик Shenandoah нацелен на сокращение времени остановок во время сборки мусора за счёт проведения большего объёма работ параллельно с выполнением Java-приложений.
  • Добавлен экспериментальный API StableValue для работы с объектами, содержащими неизменяемые данные и обрабатываемыми в JVM как константы. К подобным объектам применяются оптимизации производительности, аналогичные полям с ключевым словом «final». API StableValue, в отличие от «final», разделяет создание постоянных значений и их инициализацию, гарантирует, что значение может быть инициализировано только один раз, сокращает время запуска программ и позволяет применять в пользовательском коде оптимизации сворачивания констант (constant-folding), ранее использовавшиеся только во внутреннем коде JDK.
    
       class Application {
           // Было:
           // static final UserService USERS = new UserService();
           // Теперь можно:
           static final StableValue‹UserService› USERS = StableValue.of();
    
           public static UserService users() {
              return USERS.orElseSet(UserService::new);
           }
        }
    
  • Добавлен экспериментальный API для кодирования и декодирования объектов с криптографическими ключами, сертификатами и списками отозванных сертификатов, используя формат PEM (Pivacy-Enhanced Mail).
  • Добавлена поддержка ограниченных значений (Scoped Values), позволяющих совместно использовать неизменяемые данные в потоках и эффективно обмениваться данными между дочерними потоками (значения наследуются). Scoped Values создан для замены механизма переменных локальных к потоку (thread-local variables) и более эффективен при использовании очень большого числа виртуальных потоков (тысячи и миллионы потоков). Главное отличие Scoped Values от переменных локальных к потоку в том, что первые записываются один раз, в дальнейшем не могут быть изменены и остаются доступны только на время выполнения потока.
  • Добавлен API для использования криптографических функций формирования ключа (KDF, key derivation function), позволяющих сформировать дополнительные ключи необходимой длины на основе секретного ключа (например, пароля) и произвольного набора данных.
  • Разрешено указание в конструкторах выражений перед вызовом super(…), используемом для явного вызова конструктора родительского класса из конструктора наследуемого класса, если эти выражения не ссылаются на создаваемый конструктором экземпляр.
    
       class Outer {
           void hello() {
               System.out.println("Hello");
           }
           class Inner {
               Inner() {
                   hello();
                   super();
               }
           }
       }
    
  • Упрощено создание кэша для упреждающей (Ahead-of-Time) загрузки и компоновки классов, позволяющего ускорить запуск HotSpot JVM за счёт задействования классов в уже загруженном и скомпонованном состоянии.
    При запуске больше не требуется отдельных операций для записи активности и создания кэша, и достаточно одной команды:

    
       java -XX:AOTCacheOutput=app.aot -cp app.jar com.example.App ...
    
  • При старте HotSpot Java VM реализована возможность использования профилей выполнения методов, полученных при прошлом запуске приложения. Изменение позволяет JIT-компилятору обойтись без стадии накопления статистики и сразу начать генерировать нативный код без ожидания формирования профиля.
  • В HotSpot JVM реализована поддержка компактных заголовков объектов, размер которых на 64-разрядных системах уменьшен с 96 до 64 бит (с 12 до 8 байт). Уменьшение размера заголовков позволяет сократить размер кучи и повысить эффективность работы кэша.
  • Предложена тестовая реализация API Vector, предоставляющего функции для векторных вычислений, которые выполняются с использованием векторных инструкций процессоров x86_64 и AArch64 и позволяют одновременно применить операции сразу к нескольким значениям (SIMD). В отличие от предоставляемых в JIT-компиляторе HotSpot возможностей по автовекторизации скалярных операций, новый API даёт возможность явно управлять векторизацией для параллельной обработки данных.
  • Предложен для тестирования пятый предварительный вариант API для cтруктурированного параллелизма (Structured Concurrency), упрощающего разработку многопоточных приложений за счёт обработки нескольких задач, выполняемых в разных потоках, как единого блока.
  • В механизме сопоставления с образцом предложен третий предварительный вариант возможности использования примитивных типов (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 ...
       }
    
  • В JDK Flight Recorder (JFR) добавлена экспериментальная поддержка профилирования с более точным отслеживанием потребления ресурсов CPU на платформе Linux. Информация о времени выполнения различных конструкций может быть наглядно визуализирована с использованием цветных диаграмм «FlameGraph«.
  • В JDK Flight Recorder (JFR) при асинхронном сэмплировании стеков потоков Java повышена стабильность работы за счёт обхода стека вызовов только в «безопасных точках» (safepoints).
  • В JDK Flight Recorder (JFR) добавлены средства трассировки и оценки времени выполнения методов.
    Поддерживается трассировка стека вызовов конкретных методов и запись точной статистики о вызовах методов, охватывающей такие метрики, как время выполнения и количество вызовов.

  • Удалён код и сборочные сценарии для поддержки 32-разрядных систем x86. Прекращение поддержки 32-разрядных систем x86 упростило инфраструктуру для сборки и тестирования JDK, а также позволило реализовывать возможности, завязанные на аппаратные платформы, без создания fallback-обработчиков для 32-битных систем x86.

Дополнительно можно отметить публикацию обновления платформы для создания приложений с графическим интерфейсом JavaFX 25 и выпуск универсальной виртуальной машины GraalVM 25, поддерживающей запуск приложений на JavaScript (Node.js), Python, Ruby, R, любых языках для JVM (Java, Scala, Clojure, Kotlin) и языках, для которых может формироваться биткод LLVM (C, C++, Rust).

Источник: http://www.opennet.ru/opennews/art.shtml?num=63895