Ссылка для скачивания: http://jdk.java.net/10/.
Последнюю полвину года мы подробно обсуждали здесь новшества Java 10 и знаем их наизусть.
Но было бы странно, если самая главная Java-новость за полгода не появилась бы в этом хабе.
Как говорится, просто оставлю это здесь. Вперёд к приключениям!
Действительно вышла в срок?
Да, действительно. Релиз сделали из 46 билда, и собрали день назад, глядите:
$ java -version
openjdk version "10" 2018-03-20
OpenJDK Runtime Environment 18.3 (build 10+46)
OpenJDK 64-Bit Server VM 18.3 (build 10+46, mixed mode)
А в IDE работает, или всё красным перечёркнуто?
Работает в свежей IntelliJ IDEA. Но придётся поставить бета-версию (например, ideaIU-181.4203.400
), потому что на стабильной 2017.3.5
не поддерживается этот language level.
Долгий путь к релизу
На самом деле, нет. Это самый быстрый полноценный релиз в истории!
Раньше план публиковался на странице проекта, но больше он нам не понадобится. Все этапы успешно выполнены.
- 2017/12/14 Первая фаза замедления
- 2018/01/11 All Tests Run
- 2018/01/18 Вторая фаза замедления
- 2018/02/08 Первый Release Candidate
- 2018/02/22 Окончательный Release Candidate
- 2018/03/20 General Availability
И что, всё хорошо?
В основном, да. В этом релизе разработчики фокусировались на починке только тех багов, которые являются совершенно критичными для успеха Java 10. Все задачи, относящиеся к другим релизам Java, даже с высшим приоритетом, отложены.
Но какой же релиз без хорошего факапа? Тагир Валеев (lany) через считаные часы опубликовал в своём твиттере новость об эпическом новом баге в компиляторе.
Баг уже обсуждают в рассылке и ведётся работа по его починке.
Вот этот код, можно вставить и проверить:
public class Main {
void m() {
var s = java.util.List.of("a", 1);
}
}
Проблема проявляется только только при включённом флаге -g
, который говорит о необходимости генерации отладочной информации. В IDE он включён по-умолчанию, так что мимо ошибки не пройти :-)
Изменения, которые появятся в этом релизе
Локальный вывод типов с помощью var
. Неоднозначная фича. Регулярно вызывает бурления в рассылке.
Пример кода:
var list = new ArrayList<String>(); // infers ArrayList<String>
var stream = list.stream(); // infers Stream<String>
Бородатый анекдот в тему.
Заходит джавист в столовую и говорит: дайте, пожалуйста, Борщ борщ нью Борщ!
JEP 296: Консолидация леса исходников JDK в едином репозитории.
Широкой общественности обычно не интересно, разве что ты собираешь OpenJDK из исходников. Интересней то, что чем меньше хаоса в проекте, тем более качественный получается продукт.
Улучшение изоляции основных исходников от GC путём создания хорошего чистого интерфейса для GC. В последнее время стало весьма популярным писать свои GC: на подходе у нас Shenandoah, ZGC, Epsilon. Чтобы поддержать эти благие начинания, разработчикам OpenJDK пришлось конкретно разгрести свалку в коде, чтобы не только максимально упроситить создание новых GC, но и дать возможность быстро отключать ненужные GC из сборки. Один из основных критериев успеха — отсутствие просадки по перфомансу после всех этих рефакторингов.
CMS выбросили на мороз, и всё интересное в общеупотребительной (не низкопаузной) сборке мусора теперь происходит в G1. Читаем "Release Note: JEP 307: Parallel Full GC for G1": «Коллектор G1 создан для того, чтобы обходиться без full GC, но когда параллельная сборка не может утилизировать память достаточно быстро, происходит возвращение к full GC. Старая реализация full GC в G1 использовала однопоточный алгоритм mark-sweep-compact. После реализации JEP-307, full GC параллелизовался и стал использовать то же количество параллельных тредов-воркеров, как в young и mixed». (Напоминаю, что young GC обрабатывает только регионы young/survivor, mixed — ещё и old, full — весь хип, young/tenured).
JEP 310: Application Class-Data Sharing.
Чтобы ускорить запуск и уменьшить количество используемой памяти, предлагается расширить существующую фичу под названием Class-Data Sharing («CDS») возможностью упаковки классов в общий архив.
Если совсем коротко, то вот так архив вначале создаётся, а потом используется при запуске:
java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=hello.lst -XX:SharedArchiveFile=hello.jsa -cp hello.jar
java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=hello.jsa -cp hello.jar HelloWorld
Возможность выполнять колбэк на тредах, не делая глобальный для JVM сейфпоинт. Фича позволяет дешёво останавливать одиночные треды, а не только «всё или ничего». Это низкоуровневая системная фича, вручную ей воспользоваться нельзя, но можно радоваться автомагически возросшей производительности программ.
JEP 313: Remove the Native-Header Generation Tool.
Утилита javah
больше не нужна, потому что нативные заголовки теперь может делать javac (начиная с JDK8, на самом деле).
javah
была утилитой, генерирующей сишные заголовочные файлы и исходники, необходимые для использования нативных методов. Сгенерированные ей файлы предназначены для использования в программах, написанных на Си, чтобы обращаться к экземплярам джавовых объектов из неуправляемого нативного кода. В .h-файле определяется структура, которая выглядит примерно как класс, которым мы собираемся управлять. Поля структуры — переменные экземпляра класса. Тем не мнее, в JNI использование подобных стабов не является обязательным.
Поддержка новых расширений Unicode: cu (currency type), fw (first day of week), rg (region override), tz (time zone).
HotSpot VM теперь может выделять хиповую память на других девайсах, например, на NV-DIMM. Некоторые операционки уже умеют выделять не-DRAM память, помещая её на файловую систему, например, NTFS DAX и ext4 DAX. Добавляется опция ` -XX:AllocateHeapAt=.
Graal, можно использовать как основной JIT-компилятор. Объяснять, что такое Graal — очень долго, поэтому вкратце. Под брендом Graal сейчас объединено несколько направлений: Graal Compiler, SubstrateVM, Truffle, различные языки для него ("Graal polyglot runtime"). В данном случае имеется в виду именно Compiler. На некоторых тестах, типа Scala DaCapo, грааль позволяет получить почти двухкратную производительность по сравнению с C2! Чтобы получить подобные чудесные результаты, необходимо иметь очень-очень много динамического кода и очевидно, наибольшую пользу тут извлекут программисты на Scala, Groovy, JavaScript, и т.п. Работает это чудо пока что только на 64-битных Linux и macOS.
В JDK имеется кейстор cacerts
, который нужен для хранения корневых сертификатов. Но в OpenJDK он пока пустой. Поэтому ништяки типа TLS в OpenJDK по-умолчанию не работают. Теперь этот cacerts
будет правильно сконфигурирован и заполнен, и ништяки начнут работать. Кроме того, это сгладит разницу между OpenJDK и Oracle JDK.
Feature releases будут добавлять новые фичи. Update releases будут только чинить баги.
Ну и конечно же,
$ java -version
openjdk version "10" 2018-03-20
OpenJDK Runtime Environment 18.3 (build 10+46)
OpenJDK 64-Bit Server VM 18.3 (build 10+46, mixed mode)
Не всё есть в JEP
В багтрекере и рассылке можно увидеть большое количество изменений, которые не получили такую широкую огласку, как основные JEP.
По этому поводу Тагир Валеев (lany) недавно написал очень хорошую статью: https://habrahabr.ru/post/349868/. Дублировать её содержимое нет смысла, нужно пройти по ссылке и прочитать.
Что дальше?
Необходимо взять JDK 10 и начать миграцию на него своего кода!
Ссылка на загрузку: http://jdk.java.net/10/.
Минутка рекламы. Как вы, наверное, знаете, мы делаем конференции. Ближайшая конференция по Java — JPoint 2018. Она пройдет 6-7 апреля 2018 года в Москве. В докладах часто упоминаются вопросы перехода на новые версии Java. Какие доклады там бывают — можно посмотреть в нашем архиве на YouTube или прочитать в хаброблоге. Кроме того, можно будет вживую пообщаться с докладчиками и лучими экспертами по Java-платформе в специальных дискуссионных зонах после каждого доклада. Короче, заходите, мы вас ждём.
Автор: Олег Чирухин