#java #performance #jvm #java-12
#java #Производительность #jvm #java-12
Вопрос:
Это небольшая, но заметная разница:
$ for j in {5..12}; do . chjdk $j; time (java -version; for i in {1..1000}; do java x >/dev/null; done); echo ""; done
java version "1.5.0_22"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_22-b03)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_22-b03, mixed mode)
real 2m4.988s
user 0m59.832s
sys 0m18.856s
java version "1.6.0_45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)
real 0m28.055s
user 0m24.012s
sys 0m4.216s
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)
real 0m31.225s
user 0m24.836s
sys 0m3.564s
java version "1.8.0_202"
Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)
real 0m43.463s
user 0m35.948s
sys 0m6.516s
java version "9"
Java(TM) SE Runtime Environment (build 9 181)
Java HotSpot(TM) 64-Bit Server VM (build 9 181, mixed mode)
real 1m29.909s
user 1m37.892s
sys 0m12.972s
java version "10.0.1" 2018-04-17
Java(TM) SE Runtime Environment 18.3 (build 10.0.1 10)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.1 10, mixed mode)
real 1m21.161s
user 1m24.412s
sys 0m13.044s
openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2 9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2 9, mixed mode)
real 0m56.932s
user 1m8.892s
sys 0m9.516s
openjdk version "12" 2019-03-19
OpenJDK Runtime Environment (build 12 33)
OpenJDK 64-Bit Server VM (build 12 33, mixed mode, sharing)
real 0m39.930s
user 0m38.876s
sys 0m9.520s
Что-то изменилось конкретно в рамках выпуска Java 12 или это ошибка измерения?
Обновить
Действительно, JVM загружается быстрее. Спасибо LppEdd и Holger за ссылку.
JEP 341 — архивы компакт-дисков по умолчанию.
Когда вы запускаете Java-приложение, загружаются тысячи классов, что, похоже, замедляет запуск JVM.
Совместное использование данных классов — это функция, которая была введена в качестве коммерческой функции, начиная с обновления 40 JDK 8. Это позволяет упаковать все запускаемые классы в архив определенного формата, после чего время запуска приложения увеличивается. Через некоторое время был представлен JEP 310: Класс приложения-совместное использование данных, что позволило нам делать то же самое не только с системными классами, но и с классами приложений.
Для классов JDK это выглядит следующим образом. Сначала мы выгружаем классы с помощью java -Xshare:dump
, а затем запускаем приложение, указывая ему использовать этот кэш: java -Xshare:on -jar app.jar
. И скорость запуска немного улучшилась.
Но мне показалось странным каждый раз писать -Xshare: dump
, если результат выполнения этой команды по умолчанию немного предсказуем на этапе создания дистрибутива JDK. Согласно документации, если дистрибутив Java 8 был установлен с помощью установщика, то прямо во время установки он должен выполнить необходимые для вас команды. Но почему? И что делать с дистрибутивом, который распространяется не в виде установщика, а в виде zip-архива?
Поскольку архив JDK 12 CDS будет сгенерирован создателями дистрибутива сразу после создания ссылки. Даже для ночных сборок (при условии, что они 64-разрядные и собственные, а не для кросс-компиляции).
Начиная с JDK 11, -Xshare: auto
включен по умолчанию, и такой архив будет получен автоматически. Таким образом, простое обновление до JDK 12 ускоряет запуск приложения!
Комментарии:
1. Мы не знаем, является ли это ошибкой измерения; только вы можете ответить на этот вопрос. Время запуска увеличивалось и уменьшалось в зависимости от версий; Я не уверен, почему это вопрос. Я знаю, что в последнее время они пытались решить эту проблему более конкретно, поэтому я бы предположил, что они пытаются вернуть ее к тому, какой она была в эпоху 1.6-1.8.
2. Было внесено множество небольших исправлений, направленных на улучшение запуска; по нескольку в каждой из последних версий. Они могут складываться!
Ответ №1:
Это может быть связано с JEP 341 используемыми по умолчанию архивами CDS, которые являются новыми для JDK 12.
Краткие сведения
Улучшите процесс сборки JDK для создания архива совместного использования данных классов (CDS), используя список классов по умолчанию, на 64-разрядных платформах.Цели
Улучшите время запуска «из коробки»
…
Из того, что я понял, такого же поведения можно было добиться даже в предыдущих версиях, используя параметры -Xshare:dump
/ -Xshare:on
. Этот JEP просто устанавливает его по умолчанию.
Спасибо Холгеру за статью Oracle о совместном использовании данных классов.
Комментарии:
1. Вероятно, это основная причина, поскольку номера операционной системы показывают, что JDK 8 почти на одном уровне (где CDS был создан по умолчанию в большинстве сред). В более поздних версиях произошли значительные изменения в процессе установки (поскольку были удалены несколько старых функций), включая новую опцию простой загрузки и распаковки zip-архива без фактического процесса установки, который мог бы сгенерировать архив CDS.
2. @Holger спасибо за разъяснение. Честно говоря, почти все разработчики, с которыми я говорил об этом, не знали, что такая оптимизация существует. Кажется, это не очень хорошо продавалось (или это просто считалось само собой разумеющимся).
3. Да, обработка этой функции была / остается очень странной. Об этом была статья , и в ней говорилось, что эта функция поддерживалась только для клиентской JVM, что означало, что CDS не был сгенерирован для серверной JVM во время установки, однако, сгенерировав его вручную впоследствии, это сработало. Я думаю, первоначальный план состоял в том, чтобы разработать оптимизированное модульное хранилище для Java 9, которое заменит компакт-диски; когда оно не попало в релиз, было забыто переориентироваться на компакт-диски.
4. Обратите внимание, что есть обновленная версия статьи для Java 8.
5. У Клааса Редестада есть хороший блог на эту тему: Предварительный просмотр: запуск OpenJDK 12