Глава 6. Gradle Демон.

Gradle запускается на Виртуальной Машине Java (JVM) и использует несколько вспомогательных библиотека, которые требует некоторое время для инициализации. В результате, это иногда может замедлить запуск. Решение этой проблемы находится в Демоне Gradle: долгоживущий процесс запущенный на заднем плане, который выполняет ваши сборки быстрее, чем было бы без его использования. Ускорение достигается за счет пропуска затратного по времени процесса инициализации, а еще благодаря использованию кэшированию, которое хранит ваш проект в памяти. Запуск Gradle с демоном ничем не отличается от запуска без него. Просто настройте, хотите ли вы его использовать или нет - все остальное прозрачно обрабатывается Gradle'ом.

6.1. Почему использование демона Gradle важно для производительности.

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

Рассуждения просты: улучшаем скорость сборки используя рассчеты предыдущих сборок. Однако, преимущества значительны: мы можем снизить время сборки на 15-75% при последующих запусках. Мы рекомендуем вам проанализировать вашу сборку с помощью опции --profile, чтобы получить представление о том, какое влияние оказывает демон в вашем случае.

С версии Gradle 3.0, демон включен по умолчанию, так что вам даже не придется ничего делать, чтобы воспользоваться его преимуществами.

6.2. Вывод статуса демона.

Для получения списка запущенных демонов и их статусов, используйте команду --status.

Примерный вывод запуска команды:

  PID VERSION                 STATUS
28411 3.0                     IDLE
34247 3.0                     BUSY
	  

На текущий момент, определенная версия Gradle может подключаться только к демонам той же самой версии. Это значит, что вывод статуса покажет демонов только для той версии Gradle, в которой была выполнена команда, но не для других версий. Будущие версии Gradle снимут это ограничение и будут показывать запущенных демонов для всех версий.

6.3. Отключение демона.

Демон Gradle включен по умолчанию и мы рекомендуем всегда его включать на машинах разработчиков. Есть несколько способов отключить демона, но наиболее общий - добавить строчку

org.gradle.daemon=false
	  

в файл «USER_HOME»/.gradle/gradle.properties, где «USER_HOME» - это ваша домашняя папка. Обычно, это одна из следующих папок, в зависимости от платформы:

  • C:\Users\ (Windows Vista & 7+)
  • /Users/ (Mac OS X)
  • /home/ (Linux)

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

Как только вы глобально включили демона таким способом, все ваши сборки получает ускорение, в независимости от версии Gradle, используемой для каждой конкретной сборки.

6.4. Остановка запущенного демона.

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

Выполнение этой команды завершит все процессы демонов, которые были запущены той же версией Gradle, что и версия, используемая для запуска команды завершения. Если у на машине установлен Набор Разработки Java (JDK), то вы можете убедиться, что демон был остановлен с помощью команды jps. Вы распознаете любого демона Gradle по имени GradleDaemon.

6.5. FAQ.

6.5.1. Как я могу отключить демона Gradle?

Есть два рекомендуемых способа отключить демона постоянно для окружения:

  • С помощью переменных окружения: добавьте флаг -Dorg.gradle.daemon=false к переменной окружения GRADLE_OPTS
  • С помощью файла свойств: добавьте org.gradle.daemon=false в файл «GRADLE_USER_HOME»/gradle.properties

Обратите внимание, что «GRADLE_USER_HOME» по умолчанию «USER_HOME»/.gradle, где «USER_HOME» - домашняя папка текущего пользователя. Данное местоположение может быть настроено с помощью переключателей командной строки -g и --gradle-user-home, так же как и с помощью переменной окружения GRADLE_USER_HOME и системного свойства JVM org.gradle.user.home.

Оба подхода ведут к одному результату. Какой из них использовать, зависит от личных предпочтений. Большинство пользователей Gradle выбирают второй способ и добавляют строку в пользовательский файл gradle.properties.

На Windows можно отключить демона для текущего пользователя с помощью данной команды:

(if not exist "%USERPROFILE%/.gradle" mkdir "%USERPROFILE%/.gradle") && (echo. >> "%USERPROFILE%/.gradle/gradle.properties" && echo org.gradle.daemon=false >> "%USERPROFILE%/.gradle/gradle.properties")
	  

На юник-подобных операционных системах, следующая команда оболочки Bash, отключит демона для текущего пользователя:

mkdir -p ~/.gradle && echo "org.gradle.daemon=false" >> ~/.gradle/gradle.properties
	  

Как только демон отключен для окружения сборки таким способом, он не будет запущен, пока не будет явного запроса с опцией --daemon.

Опции командной строки --daemon и --no-daemon включают и выключают использование демона для индивидуального запуска сборки, когда используется интерфейс командной строки Gradle. Обычно, немного удобнее включать демона для определенного окружения (например, учетной записи пользователя), чтобы каждая сборка использовала демона и не было бы необходимости помнить, что надо передать опцию --daemon.

6.5.2. Почему больше одного процесса демона на моей машине?

Есть несколько причин, по которым Gradle может создать нового демона, вместо использования уже существующего. Основное правило заключается в том, что Gradle запускает нового демона, если не доступно ни одного бездействующего или совместимого. Gradle остановит любого демона, который бездействует 3 часа и более, так что вам нет необходимости закрывать их вручную.

бездействующий

Бездействующий демон - это тот, который не выполняет сборку или любую другую полезную работу.

совместимый

Совместимый демон - это тот, который удовлетворяет (или можно сделать, чтобы удовлетворял) требованиям окружения сборки. Среда выполнения Java используемая для сборки - пример одного из аспектов окружения сборки. Другой пример, набор системных свойств JVM требуемых средой выполнения сборки.

Некоторые аспекты запрошенной среды сборки не могут быть предоставлены демоном. Если демон запущен в среде Java 7, но запрощенная среда Java 8, тогда демон несовместим и другой должен быть запущен. Более того, определенные свойства среды выполнения Java не могут быть изменены после того, как JVM была запущена. Например, у запущенной JVM невозможно изменить выделение памяти (-Xmx1024m), кодировку по умолчанию, региональные настройки по умолчанию и так далее.

Запрошенная "среда сборки" обычно создается неявно на основе среды сборки клиенты (например, командной строки Gradle, интеграционной средой разработки) и явно через переключатели командной строки и настройки. Для того, чтобы узнать детали определения и контроля среды сборки, смотрите Главу 12, Среда Сборки.

Ниже перечислены системные свойства JVM, которые фактически неизменны. Если требуемая среда сборки запрашивает любое из этих свойств со значением, отличным от JVM, в котором запущен демон, то демон несовместим.

  • file.encoding
  • user.language
  • user.country
  • user.variant
  • java.io.tmpdir
  • javax.net.ssl.keyStore
  • javax.net.ssl.keyStorePassword
  • javax.net.ssl.keyStoreType
  • javax.net.ssl.trustStore
  • javax.net.ssl.trustStorePassword
  • javax.net.ssl.trustStoreType
  • com.sun.management.jmxremote

Ниже перечислены атрибуты JVM, контролируемые аргументами запуска, которые фактически неизменны. Соответствующие атрибуты запрошенной среды сборки и среды демона должны в точности совпадать, чтобы демон был совместимым.

  • Максимальный размер "кучи" (т.е. аргумент JVM -Xmx)
  • Минимальный размер "кучи" (т.е. аргумент JVM -Xms)
  • Загрузочный путь к классам (т.е. аргумент JVM -Xbootclasspath)
  • Статус "утверждения" (т.е. аргумент -ea)

Требуемая версия Gradle еще один аспект запрошенной среды сборки. Процесс демона привязан к определенной среде выполнения Gradle. Работа с несколькими проектами Gradle, которые используют разные версии Gradle, во время сессии, обычная причина нескольких запущенных процессов демона Gradle.

6.5.3. Сколько памяти использует демон и как я могу увеличить доступную ему память?

Если запрошенная среда сборки не определяет максимальный размер "кучи", то демон использует до 1 гигабайта "кучи". В качестве минимального размера "кучи", используется заданные по умолчанию для вашей JVM. Одного гигабайта более чем достаточно для большинства сборок. Большие сборки с сотнями проектов, тоннами настроек и исходных кодов, могут потребовать, или будет выполняться лучше, больше памяти.

Для увеличения количества памяти, которые может использовать демон, установите соответствующие флаги запрошенной среды сборки. Если интересны детали, смотрите Главу 12 Среда Сборки.

6.5.4. Как я могу остановить демона?

Процессы демона автоматически завершат сами себя по прошествии трех часов или более бездействия. Если вы желает остановить процесс демона до этого момента, вы можете "убить" процесс с помощью средств операционной системы или запустить команду gradle --stop. Gradle, при использовании переключателя --stop, запросит все запущенные процессы демона, той же самой версии, что и версия из которой была запущена комана, завершиться.

6.5.5. Что может пойти не так при использовании демона?

Значительные инженерные усилия пошли на то, чтобы сделать демона надежным, прозрачным и ненавязчивым во время ежедневной разработки. Однако, процессы демона могут быть повреждены или перестать отвечать. Сборка Gradle выполняет произвольный код из различных источников. Хотя сам Gradle разработан и тестировался для работы с демоном, пользовательские скрипты сборки или сторонние плагины могут дестабилизировать процесс демона из-за, например, утечек памяти или повреждения глобального состояния.

Также возможно дестабилизировать демон (или среду сборки в общем), запуская сборки, которые не освобождают ресурсы правильно. В особенности это актуальная проблема при использовании Microsoft Windows, т.к. она более строга к программам, которые не закрывают файлы после чтения или записи.

Gradle активно отслеживает использование "кучи" и пытается определить, когда утечка исчерпывает доступное место в "куче" в демоне. Когда он определяет проблему, демон Gradle завершает текущую запущенную сборку и качестве профилактики перезапускает демона на следующей сборке. Отслеживание включено по умолчанию, но может быть отключено установкой системного свойства org.gradle.daemon.performance.enable-monitoring в false.

Если вы подозреваете, что процесс демона стал нестабильным, его можно просто "убить". Помните, что переключатель --no-daemon может быть установлен, чтобы предотвратить использование демона. Это может быть полезно для определения, демон ли Gradle является преступником или нет.

6.6. Когда не надо использовать демона Gradle.

Рекомендуется использовать демон во всех средах разработчиков. Но для сред серверов сборки и Непрерывной Интеграции рекомендуется отключать демона.

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

6.7. Инструменты и Интегрированные Среды Разработки.

Инструментальное API Gradle (смотрите Главу 14, Встраивание Gradle с помощью Инструментального API), которое используется Интеграционным Средами Разработки и другими инструментами для интеграции Gradle, всегда использует демона для выполнения сборок. Если вы выполняете сборки Gradle из вашей IDE, вы используете демона Gradle и нет необходимости включать его для вашей среды.

Однаком, если вы явно не включили демона Gradle для вашей среды, ваши сборки из командной строки не будут его использовать.

6.8. Как демон Gradle ускоряет сборку?.

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

Значимую часть в производительности современной JVM занимает оптимизация кода во время выполнения. Например, HotSpot (реализация JVM предоставляемая Oracle и лежащая в основе OpenJDK) применяет оптимизации к коду во время выполнения. Оптимизация постепенная и не мгновенная. То есть, код постепенно оптимизируется во время выполнения, означая, что последующие сборки могут быть быстрее только благодаря процессу оптимизации. Эксперименты с HotSpot показали, что может пройти от 5 до 10 сборок, прежде чем оптимизация стабилизируется. Разница в субъективном времени сборки между первой и десятой при использовании демона может быть очень существенной.

Демон также дает возможность эффективно кэшировать информацию в памяти. Например, классы, необходимые для сборки (плагины, сборочные скрипты), могут сохраняться в памяти между сборками. Похожим образом, Gradle может сохранять кэши в памяти для таких данных сборки, как хэши для входных и выходных данных задач, используемых для последовательной сборки

6.8.1. Возможные будущие улучшения.

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

Есть много других способов сделать так, чтобы демон Gradle собирал сборки еще быстрее в будущих версиях Gradle