Следующее обновление Java, которое выйдет в марте 2021 года, включает новый менеджер памяти для Metaspace, поддержку в исходном коде JDK языковых функций C++ 14 и векторный API (Vector API)
Пол Крилл, ведущий редактор Infoworld | 4 ноября 2020 года
В Java Development Kit (JDK) 16 в конце октября были добавлены еще две предлагаемые новые функции, API доступа к внешней памяти и сопоставления с образцом (прим.пер. Pattern Matching). Ранее предложенные функции включают в себя готовый к производству инструмент для упаковки приложений, thread-stack процессинг при сборке мусора, поддержку функций языка C++ 14 и возможность “эластичного metaspace” для более быстрого возврата неиспользуемой памяти для метаданных классов в ОС.
JDK 16 будет эталонной реализацией версии стандартного набора Java, следующей за JDK 15, вышедшим 15 сентября. График выпуска JDK 16 предполагает стадии рампдаунов(пре-релизов) 10 декабря и 14 января 2021 года, а затем 4 февраля и 18 февраля 2021 года выпускаются релиз-кандидаты. Промышленный релиз намечен на 16 марта 2021 года.
По состоянию на 4 ноября 2020 года в JDK 16 официально предполагается внедрить тринадцать предложений. Новые возможности Java 16 включают:
- Перемещение thread-stack процессинга ZGC (Z Garbage Collector) из безопасных точек (safepoints) в параллельную фазу. Планируется: удаление thread-stack процессинга из безопасных точек ZGC; теперь thread-stack процессинг станет ленивым, кооперативным, параллельным и инкрементальным; удаление всех других корневых процессов для каждого потока из безопасных точек ZGC; и предоставление механизма для других подсистем виртуальной машины HotSpot для ленивой обработки стеков. ZGCпредназначен для того, чтобы сделать паузы GC и проблемы масштабируемости в HotSpot делом прошлого. До сих пор операции GC, время исполнения которых кореллировало с размером кучи и размером Metaspace, были перемещены из безопасных точек в параллельные фазы. Это такие операции как маркировка, перемещение, обработка ссылок, выгрузка классов и большая часть обработки корневых ссылок. Единственные действия, которые все еще выполняются в безопасных точках GC, — это обработка корневых подмножеств и ограниченная по времени операция завершения маркировки. Эти корневые ссылки размещались в стеках потоков Java и в других корневых ссылках, причем эти корневые ссылки были проблематичными, поскольку они дублировались в каждом потоке. Чтобы выйти из текущей ситуации, обработка каждого потока, включая сканирование стека, должна быть переведена в параллельную фазу. При таком подходе стоимость задержки должна быть незначительной, а время, затрачиваемое на безопасных точках ZGC на типичных машинах, должно составлять менее одной миллисекунды.
- Возможность эластичного Metaspace, которая быстрее возвращает в ОС неиспользуемую для метаданных память HotSpotVM, сокращает ресурсы, требуемые для Metaspace и упрощает его код, что снижает затраты на обслуживание. У Metaspace были проблемы с высоким использованием памяти вне кучи. Планируется замена существующего менеджера памяти на схему buddy-allocation, которая делит память на блоки, наиболее подходящие под запросы на выделение памяти. Этот подход был использован, среди прочего, в ядре Linux, и позволит выделять память меньшими кусками, чтобы снизить потребности загрузчика классов. Фрагментация также уменьшится. Кроме того, лениво, по мере необходимости, будут выделяться новые блоки памяти за счёт ОС, что позволит уменьшить объем памяти для загрузчиков, требующих при старте большого объёма памяти, но не использующие весь объём сразу или не нуждающиеся в их полном использовании вообще. Чтобы полностью использовать эластичность, предлагаемую buddy-allocation, память Metaspace будет организована в одинаковые по размеру блоки, которые могут выделяться или нет, независимо друг от друга.
- Включение возможностей языка C++ 14, JDK позволит использовать возможности C++ 14 в исходном коде с конкретными указаниями о том, какие из этих возможностей могут быть использованы для виртуальной машины HotSpot. В соответствии с JDK 15 языковые возможности, используемые кодом C++ в JDK, были ограничены языковыми стандартами C++ 98/03. В JDK 11 исходный код был обновлен для поддержки более поздних стандартов C++. В том числе появилась возможность сборки с последними версиями компиляторов, поддерживающих функции языка C++ 11/14. Это предложение не предлагает изменений стиля или использования кода C++, за пределами HotSpot. Но чтобы воспользоваться преимуществами возможностей языка C++, требуются некоторые изменения во время сборки, в зависимости от компилятора платформы.
- Векторный API на стадии инкубатора, в котором JDK будет оснащен модулем инкубатора,
jdk.incubator.vector
для выражения векторных вычислений, которые компилируются в оптимальные аппаратные векторные инструкции на поддерживаемых архитектурах ЦП, и позволят достичь более высокой производительности по сравнению с эквивалентными скалярными вычислениями. Vector API предоставляет механизм для написания сложных векторных алгоритмов на Java, используя уже существующую поддержку в виртуальной машине HotSpot для векторизации, но с пользовательской моделью, которая делает векторизацию более предсказуемой и надежной. Цели этого предложения включают в себя предоставление четкого и ясного API для выражения целого ряда векторных вычислений, будучи платформо-независимым за счёт поддержки нескольких архитектур процессоров, а также предлагая надежную компиляцию во время выполнения и производительность на архитектурах x64 и AArch64. Целью также является отказоустойчивость, когда векторное вычисление будет постепенно деградировать, но продолжать исполняться, если оно не может быть полностью выражено в runtime (во время выполнения) в виде последовательности аппаратных векторных инструкций, либо потому, что архитектура не поддерживает некоторые инструкции, либо не поддерживается архитектура процессора. - Перенос JDK на платформу Windows/AArch64. Выпуск нового класса серверов и потребительского оборудования вызвал спрос, сделавший AArch64 (ARM64) Windows/AArch64 важной платформой. Хотя само портирование уже в основном завершено, основное внимание в этом предложении уделяется интеграции порта в магистральный репозиторий JDK.
- Перенос JDK на AlpineLinux и другие дистрибутивы Linux, использующие musl в качестве основной библиотеки C, на архитектуры x64 и AArch64. Musl-это Linux-реализация функциональности стандартной библиотеки, описанной в стандартах ISOC и Posix. AlpineLinuxшироко распрстранена в облачном развертывании, микрослужбах, и контейнер-среде благодаря небольшому размеру образа. Размер образа Docker для Linux меньше 6 МБ. Готовность Jawa к работе «из коробки» позволит в Tomcat, Jetty, Spring, и другим популярным платформам сразу нативно работать в таких условиях. Используя jlink для уменьшения размера Java runtime, пользователь может создать еще меньший образ, адаптированный для запуска конкретного приложения.
- Предоставление классов записей (Records), которые действуют как прозрачные носители для неизменяемых данных. Записи можно считать набором данных. Записи были предварительно представлены в JDK 14 и JDK 15. Это является ответом на жалобы на излишнюю многословность Java, и на то, что она содержала слишком много «церемоний». Цели включают в себя разработку объектно-ориентированной конструкции, которая просто агрегирует значения, помогая разработчикам сосредоточиться на моделировании неизменяемых данных, а не на расходящихся вариантах поведения, автоматически реализуя такие методы, как equals и accessors, и соответствует давнему принципу Java — строгой типизации.
- Добавление каналов сокетов Unix-domain, в которых поддержка сокетов Unix-domain (AF_UNIX) добавляется к API-интерфейсам socketchannel и serversocketchannel в пакете nio.channels. План также расширяет механизм наследования для поддержки каналов сокетов Unix-домена и каналов сокетов сервера. Unix-сокеты используются для межпроцессного взаимодействия на одном узле. Они во многих отношениях похожи на сокеты TCP/IP, за исключением того, что адресация происходит именами путей файловой системы, а не IP-адресами и номерами портов. Цель новой возможности-поддержка всех функций Unix-доменных каналов сокетов, которые являются общими для основных платформ Unix и Windows. Каналы сокетов Unix-домена будут вести себя так же, как существующие каналы TCP/IP с точки зрения чтения/записи, настройки соединения, приема входящих соединений серверами и мультиплексирования с другими неблокирующими каналами в селекторе. Сокеты Unix-домена являются более безопасными и более эффективными, чем петлевые соединения TCP/IP для локальных межпроцессных коммуникаций.
- API доступа к внешней памяти, позволяющий Java-программам безопасно обращаться к внешней памяти за пределами кучи Java. Ранее инкубированный как в JDK 14, так и в JDK 15, API доступа к внешней памяти будет повторно инкубирован в JDK 16, с добавлением уточнений. Изменения включая более четкое разделение ролей между интерфейсами
MemorySegment
иMemoryAddresses
. Цели этого предложения включают предоставление единого API для работы с различными видами внешней памяти, включая собственную, постоянную и управляемую память кучи. API не должны подрывать безопасность виртуальной машины Java. Это предложение мотивированно тем, что многие программы Java, такие как Ignite, Memcached и MapDB, обращаются к внешней памяти. Но Java API не предоставляет удовлетворительного решения для доступа к внешней памяти. - Сопоставление с образцом для оператора instanceof, который также был предварительно просмотрен как в JDK 14, так и в JDK 15. Он будет доработан в JDK 16. Сопоставление с образцом позволяет более сжато и безопасно выразить общую логику в программе, а именно условное извлечение компонентов из объектов.
- Предоставление инструмента для упаковки автономных Java-приложений. Введенный в качестве инкубационного инструмента в JDK 14, jpackage оставался в инкубации в JDK 15. С JDK 16 jpackage переходит в производство, поддерживая собственные форматы пакетов, чтобы дать пользователям опыт нормальной установки и позволить задавать параметры времени запуска во время упаковки. Форматы включают msi и exe в Windows, pkg и dmg в MacOS, а также deb и rpm в Linux. Инструмент может быть вызван непосредственно из командной строки или программно. Новый инструмент упаковки решает ситуацию, в которой многие приложения Java должны быть установлены на собственных платформах первоклассным способом, а не помещены на путь класса или путь модуля. Необходим устанавливаемый пакет, подходящий для нативной платформы.
- Миграция репозиториев исходного кода OpenJDK из Mercurial в Git. Причиной этих изменений являются преимущества в размере метаданных системы контроля версий, а также доступные инструменты и хостинг.
- Миграция на GitHub, связанная с миграцией Mercurial-to-Git, с репозиториями исходного кода JDK 16, которые будут находиться на популярном сайте код-шэринга. Переход на Git, GitHub и Skara для Mercurial JDK и JDK-sandbox был произведен 5 сентября и остается открытым для участия.
Сборки раннего доступа JDK 16 для Linux, Windows и MacOS можно найти по адресу jdk.java.net. Как и JDK 15, JDK 16 будет краткосрочным релизом, поддерживаемым в течение шести месяцев. JDK 17, ожидаемый в сентябре 2021 года, будет выпуском с долгосрочной поддержкой (LTS), и будет поддерживаться в течение нескольких лет. Текущая версия LTS, JDK 11, была выпущена в сентябре 2018 года.
Перевод Академии Progwards