Подтвердить что ты не робот

Как ускорить запуск Java VM (JVM)?

Я запускаю тесты, которые запускают несколько процессов JVM. Сводное время запуска JVM довольно значимо по сравнению со временем фактических тестов, которые запускаются внутри JVM. Как ускорить процесс?

Я уже использовал параметр "-client", это помогает, но не так сильно, как я хотел. Есть ли другой способ, например, предустановить кучу JVM и каким-то образом использовать их?

4b9b3361

Ответ 1

Если вы хотите повторно использовать JVM, "как-то" может быть Nailgun. Nailgun поддерживает JVM, а затем использует легкий собственный клиент для запуска определенного класса и обработки консоли io. Это полезно для запуска небольших утилит Java командной строки, но при повторном использовании того же JVM можно накапливать состояние.

Чтобы работать с накоплением штата, ценой запуска нескольких JVM, другой параметр Drip. Drip сохраняет новую JVM в резерве с правильной дорожкой классов и другими параметрами JVM, чтобы вы могли быстро подключиться и использовать ее по мере необходимости, а затем выбросить. Капельница хэширует параметры JVM и сохраняет информацию о том, как подключиться к JVM в каталоге с хеш-значением в качестве его имени.

Ответ 2

Почему бы не загрузить все тесты в одной JVM? Можете ли вы выполнить одно или несколько из следующих действий?

  • загрузить все тесты через класс более высокого уровня?
  • укажите тестовые классы в списке (файл конфигурации) и загрузите их последовательно через Class.forName()?
  • Если изоляция важна, вы можете создать различный загрузчик классов для каждого теста

Если распределение памяти является значительным, это может ускорить процесс, указав размер запуска JVM-памяти на тот же показатель, что и максимальная выделяемая память (-Xms vs -Xmx), что позволит сохранить JVM, чтобы вернуться к ОС для большей памяти. Однако в этом сценарии я думаю, что вряд ли это будет проблемой.

Ответ 3

Чтобы добавить к сказанному другими, следующая версия Java ( Java 7 Java 8 Java 9) должна добавить новое усовершенствование в моменты запуска JVM, из-за модуляции платформы, согласно эта ссылка.

Цитата:

Одним из преимуществ модуляции является то, что платформа - это меньшая загрузка, потенциально улучшение запуска представление. Имея меньшую память площадь повышения производительности, особенно для настольных приложений.

Ответ 4

Запустите тесты с Java 5 или лучше. Время запуска значительно сократилось для Java 5.

Вы не можете получить намного быстрее, если не сможете повторно использовать запущенную виртуальную машину: предварительная подготовка большого количества из них и последующее выполнение одного теста в каждом случае не ускорят ваши тесты.

Итак, вам нужно указать способ запуска нескольких тестов в одной виртуальной машине.

Ответ 5

Производительность запуска JVM может быть улучшена по-разному: CDS, прямая настройка, пиннинг CPU и jlink (с JDK 9) могут быть хорошими вариантами. AOT (JDK 9, только для Linux) имеет некоторые грубые грани, но может быть настроен на то, чтобы помочь небольшим приложениям.

CDS

Обмен данными с классами был разработан для клиентской VM еще в 1.5, но был значительно улучшен, так как для работы над всеми вариантами HotSpot (все GC с 8), что значительно улучшает производительность запуска при включении.

CDS всегда включена на 32-разрядных установках клиента JRE, но может потребоваться некоторые ручные шаги для включения в другом месте:

  • Запустите java -Xshare:dump, чтобы создать общий архив CDS.
  • Добавьте -Xshare:auto в свою команду, чтобы убедиться, что она используется

Другая настройка

Хотя -client может или не может вообще что-либо сделать (JVM во многих системах не поставляется с клиентской VM - нет с 9, на самом деле), существует множество способов настроить JVM сервера HotSpot, чтобы вести себя как клиентская VM:

  • Используйте только компилятор C1 (клиент): -XX:TieredStopAtLevel=1
  • Используйте как можно меньше потоков компилятора: -XX:CICompilerCount=1
  • Используйте однопоточный последовательный GC: -XX:+UseSerialGC
  • Ограничение использования кучи (особенно на больших системах), например -Xmx512m

Этого должно быть достаточно, чтобы ускорить запуск небольшого приложения с коротким сроком действия, но может иметь очень негативные последствия для максимальной производительности. Вы можете, конечно, получить еще больше, отключив функции, которые вы, возможно, не используете, например -XX:-UsePerfData (отключает некоторую информацию во время выполнения, используя MXBeans и jvmstat).

Дополнительно

  • jlink - это новый инструмент, доступный в Java 9, который позволяет создавать пользовательские изображения во время выполнения. Если ваше консольное приложение использует только небольшое подмножество модулей JDK, пользовательское время выполнения может быть сделано очень маленьким, что может улучшить время запуска. Минимальное изображение, включающее только модуль java.base, и может увеличить время запуска на ~ 10-20 мс в зависимости от аппаратного обеспечения и другой настройки: $JAVA_HOME/bin/jlink --add-modules java.base --module-path $JAVA_HOME/jmods --output jbase

  • (только для Linux) Java 9 представляет экспериментальный компилятор AOT, jaotc, который может использоваться для поддержки загрузки приложений быстрее и тратить намного меньше циклов. Из-за коробки он может замедлить немедленный запуск (поскольку код AOT'd является общей библиотекой, которая добавляет свои собственные накладные расходы ввода-вывода, не поддерживает Serial GC..), но при тщательной настройке мы, мы видели, что он сокращает время запуска небольших приложений на 15-30%.

  • Фиксирование ЦП: на больших системах мы видели эффекты, связанные с трафиком когерентности кэша между сокетами, а привязка к одному процессору node может значительно сократить время запуска. В Linux что-то вроде numactl --cpunodebind=0 $JAVA_HOME/bin/java ... должно сделать трюк.

В целом мы смогли получить минимальные приложения для выполнения всего за 35 мс (JDK 9 GA). Различные оптимизации запуска вошли в ветку JDK10, и теперь я вижу цифры всего 28 мс.

Ответ 6

Если вам действительно необходимо запустить отдельную виртуальную машину для каждого теста, лучшим вариантом является, вероятно, убедиться, что вы используете один из новейших выпусков VM от Sun. Время запуска значительно уменьшилось по сравнению с последними версиями Java и с 1.6.0_16, простая программа "Hello world" занимает около 0,2 с для моей системы.

Если бы ваш вопрос скорее заключался в том, чтобы "запускать больше тестов в одной виртуальной машине", самый простой подход зависит от того, какую тестовую структуру вы используете (если вы не используете фреймворк, вы действительно должны это учитывать). С помощью JUnit и, возможно, цели ant для JUnit вы можете использовать шаблоны для соответствия тестам, которые вы хотите запустить, или, альтернативно, присоединиться к различным тестовым классам в тестовом наборе, который затем может быть запущен на одной виртуальной машине.