Компиляция и кэши в плагине Kotlin для Gradle
На этой странице вы узнаете о следующих темах:
Инкрементальная компиляция
Плагин Kotlin для Gradle поддерживает инкрементальную компиляцию, которая включена по умолчанию для проектов Kotlin/JVM и Kotlin/JS. Инкрементальная компиляция отслеживает изменения файлов в пути к классам между сборками, чтобы компилировались только файлы, на которые повлияли эти изменения. Этот подход работает с кэшем сборки Gradle и поддерживает пропуск компиляции.
В Kotlin/JVM инкрементальная компиляция опирается на снимки пути к классам, которые фиксируют структуру API модулей и позволяют определить, когда требуется повторная компиляция. Для оптимизации всего конвейера компилятор Kotlin использует два типа снимков пути к классам:
Детализированные снимки: содержат подробную информацию о членах классов, например свойствах и функциях. При обнаружении изменений на уровне членов компилятор Kotlin повторно компилирует только классы, зависящие от изменённых членов. Для обеспечения производительности плагин Kotlin для Gradle создаёт укрупнённые снимки для файлов
.jarв кэше Gradle.Укрупнённые снимки: содержат только хэш ABI класса. Если часть ABI изменяется, компилятор Kotlin повторно компилирует все классы, зависящие от изменённого класса. Это полезно для классов, которые меняются редко, например для внешних библиотек.
Отключить инкрементальную компиляцию можно несколькими способами:
Установите
kotlin.incremental=falseдля Kotlin/JVM.Установите
kotlin.incremental.js=falseдля проектов Kotlin/JS.-
Используйте
-Pkotlin.incremental=falseили-Pkotlin.incremental.js=falseв качестве параметра командной строки.Этот параметр нужно добавлять при каждой последующей сборке.
При отключении инкрементальной компиляции инкрементальные кэши становятся недействительными после сборки. Первая сборка никогда не бывает инкрементальной.
Подробнее о том, как работает наш текущий подход к инкрементальной компиляции и чем он отличается от предыдущего, читайте в нашей публикации в блоге.
Поддержка кэша сборки Gradle
Плагин Kotlin использует кэш сборки Gradle, который сохраняет результаты сборки для повторного использования в будущих сборках.
Чтобы отключить кэширование для всех задач Kotlin, задайте системному свойству kotlin.caching.enabled значение false (запустите сборку с аргументом -Dkotlin.caching.enabled=false).
Поддержка кэша конфигурации Gradle
Плагин Kotlin использует кэш конфигурации Gradle, который ускоряет процесс сборки, повторно используя результаты этапа конфигурации в последующих сборках.
О том, как включить кэш конфигурации, читайте в документации Gradle. После включения этой функции плагин Kotlin для Gradle начнёт использовать её автоматически.
Демон Kotlin и его использование с Gradle
Работает вместе с демоном Gradle для компиляции проекта.
Работает отдельно от демона Gradle, если проект компилируется с помощью встроенной системы сборки IntelliJ IDEA.
Демон Kotlin запускается на этапе выполнения Gradle, когда одна из задач компиляции Kotlin начинает компилировать исходный код. Демон Kotlin останавливается вместе с демоном Gradle или после двух часов бездействия, если за это время компиляция Kotlin не выполнялась.
Демон Kotlin использует ту же JDK, что и демон Gradle.
Настройка аргументов JVM демона Kotlin
Каждый из перечисленных ниже способов задания аргументов переопределяет предыдущие:
Наследование аргументов демона Gradle
По умолчанию демон Kotlin наследует определённый набор аргументов от демона Gradle, но переопределяет их любыми аргументами JVM, указанными непосредственно для демона Kotlin. Например, если добавить следующие аргументы JVM в файл gradle.properties:
org.gradle.jvmargs=-Xmx1500m -Xms500m -XX:MaxMetaspaceSize=1g
Эти аргументы будут добавлены к аргументам JVM демона Kotlin:
-Xmx1500m -XX:ReservedCodeCacheSize=320m -XX:MaxMetaspaceSize=1g -XX:UseParallelGC -ea -XX:+UseCodeCacheFlushing -XX:+HeapDumpOnOutOfMemoryError -Djava.awt.headless=true -Djava.rmi.server.hostname=127.0.0.1 --add-exports=java.base/sun.nio.ch=ALL-UNNAMED
Системное свойство kotlin.daemon.jvm.options
Если аргументы JVM демона Gradle содержат системное свойство kotlin.daemon.jvm.options, используйте его в файле gradle.properties:
org.gradle.jvmargs=-Dkotlin.daemon.jvm.options=-Xmx1500m,Xms500m
При передаче аргументов соблюдайте следующие правила:
Знак минус
-ставьте только перед аргументамиXmx,XX:MaxMetaspaceSizeиXX:ReservedCodeCacheSize.Разделяйте аргументы запятыми (
,) и не ставьте пробелы. Аргументы, следующие после пробела, будут использоваться для демона Gradle, а не для демона Kotlin.
Свойство kotlin.daemon.jvmargs
Можно добавить свойство kotlin.daemon.jvmargs в файл gradle.properties:
kotlin.daemon.jvmargs=-Xmx1500m -Xms500m
Обратите внимание: если аргумент ReservedCodeCacheSize не указан здесь или в аргументах JVM Gradle, плагин Kotlin для Gradle применяет значение по умолчанию 320m:
-Xmx1500m -XX:ReservedCodeCacheSize=320m -Xms500m
Расширение kotlin
Аргументы можно указать в расширении kotlin:
kotlin {
kotlinDaemonJvmArgs = listOf("-Xmx486m", "-Xms256m", "-XX:+UseParallelGC")
}
kotlin {
kotlinDaemonJvmArgs = ["-Xmx486m", "-Xms256m", "-XX:+UseParallelGC"]
}
Определение конкретной задачи
Аргументы можно указать для конкретной задачи:
tasks.withType<CompileUsingKotlinDaemon>().configureEach {
kotlinDaemonJvmArguments.set(listOf("-Xmx486m", "-Xms256m", "-XX:+UseParallelGC"))
}
tasks.withType(CompileUsingKotlinDaemon).configureEach { task ->
task.kotlinDaemonJvmArguments = ["-Xmx1g", "-Xms512m"]
}
Поведение демона Kotlin при работе с аргументами JVM
При настройке аргументов JVM демона Kotlin обратите внимание на следующее:
Если для разных подпроектов или задач заданы разные наборы аргументов JVM, предполагается, что одновременно могут работать несколько экземпляров демона Kotlin.
-
Новый экземпляр демона Kotlin запускается только тогда, когда Gradle выполняет соответствующую задачу компиляции и у существующих демонов Kotlin нет такого же набора аргументов JVM. Представьте, что в проекте много подпроектов. Большинству из них требуется определённый объём памяти в куче для демона Kotlin, но одному модулю требуется значительно больше (хотя его компилируют редко). В этом случае для такого модуля следует задать другой набор аргументов JVM, чтобы демон Kotlin с увеличенным размером кучи запускался только у разработчиков, которые работают именно с этим модулем.
Если следующие аргументы не указаны, демон Kotlin наследует их от демона Gradle:
-Xmx-XX:MaxMetaspaceSize-XX:ReservedCodeCacheSize. Если аргумент не указан и не унаследован, используется значение по умолчанию320m.
Демон Kotlin использует следующие аргументы JVM по умолчанию:
-XX:UseParallelGC. Этот аргумент применяется только в том случае, если не указан другой сборщик мусора.-ea-XX:+UseCodeCacheFlushing-Djava.awt.headless=true-D{java.servername.property}={localhostip}--add-exports=java.base/sun.nio.ch=ALL-UNNAMED. Этот аргумент применяется только для JDK версии 16 или выше.
Возврат к предыдущему компилятору
Начиная с Kotlin 2.0.0 по умолчанию используется компилятор K2.
Чтобы использовать предыдущий компилятор в Kotlin 2.0.0 и более поздних версиях, выполните одно из следующих действий:
-
В файле
build.gradle.ktsзадайте версию языка1.9.ИЛИ
Используйте следующий параметр компилятора:
-language-version 1.9.
Подробнее о преимуществах компилятора K2 см. в руководстве по переходу на компилятор K2.
Использование последней версии языка
Начиная с Kotlin 2.0.0, чтобы попробовать последнюю версию языка, задайте свойство kotlin.experimental.tryNext в файле gradle.properties. При использовании этого свойства плагин Kotlin для Gradle увеличивает версию языка на единицу относительно значения по умолчанию для вашей версии Kotlin. Например, в Kotlin 2.0.0 версия языка по умолчанию — 2.0, поэтому это свойство задаёт версию языка 2.1.
Также можно выполнить следующую команду:
./gradlew assemble -Pkotlin.experimental.tryNext=true
В отчётах о сборке можно найти версию языка, использованную для компиляции каждой задачи.
Отчёты о сборке
Отчёты о сборке содержат длительность различных этапов компиляции и причины, по которым компиляция не могла выполняться инкрементально. Используйте отчёты о сборке для расследования проблем с производительностью, если компиляция занимает слишком много времени или её продолжительность различается для одного и того же проекта.
Отчёты о сборке Kotlin помогают эффективнее исследовать проблемы с производительностью сборки, чем сканирования сборки Gradle, где единицей детализации является отдельная задача Gradle.
Анализ отчётов о сборке может помочь решить две распространённые проблемы, связанные с длительной компиляцией:
Сборка не была инкрементальной. Проанализируйте причины и устраните основные проблемы.
Сборка была инкрементальной, но заняла слишком много времени. Попробуйте реорганизовать исходные файлы: разделите большие файлы, храните отдельные классы в разных файлах, проведите рефакторинг больших классов, объявляйте функции верхнего уровня в разных файлах и т. д.
В отчётах о сборке также отображается версия Kotlin, используемая в проекте. Кроме того, начиная с Kotlin 1.9.0, можно посмотреть, какой компилятор использовался для компиляции кода, в сканированиях сборки Gradle.
Узнайте, как читать отчёты о сборке и как JetBrains использует отчёты о сборке.
Включение отчётов о сборке
Чтобы включить отчёты о сборке, укажите в gradle.properties, куда сохранять выходные данные отчёта:
kotlin.build.report.output=file
Для выходных данных доступны следующие значения и их комбинации:
Параметр |
Описание |
|---|---|
|
Сохраняет отчёты о сборке в удобочитаемом формате в локальный файл. По умолчанию используется |
|
Сохраняет отчёты о сборке в виде объекта в указанный локальный файл. |
|
Сохраняет отчёты о сборке в разделе |
|
Отправляет отчёты о сборке с помощью HTTP(S). Метод POST отправляет метрики в формате JSON. Текущую версию отправляемых данных можно посмотреть в репозитории Kotlin. Примеры конечных точек HTTP можно найти в этой публикации в блоге |
|
Сохраняет отчёты о сборке в формате JSON в локальный файл. По умолчанию используется |
Список доступных параметров для kotlin.build.report:
# Required outputs. Any combination is allowed kotlin.build.report.output=file,single_file,http,build_scan,json # Mandatory if single_file output is used. Where to put reports # Use instead of the deprecated `kotlin.internal.single.build.metrics.file` property kotlin.build.report.single_file=my/directory/path/some_filename # Optional. Output directory for file-based or JSON reports. Default: build/reports/kotlin-build/ kotlin.build.report.file.output_dir=kotlin-reports # Optional. Label for marking your build report (for example, debug parameters) kotlin.build.report.label=some_label
Параметры, применимые только к HTTP:
# Mandatory. Where to post HTTP(S)-based reports kotlin.build.report.http.url=http://127.0.0.1:8080 # Optional. User and password if the HTTP endpoint requires authentication kotlin.build.report.http.user=someUser kotlin.build.report.http.password=somePassword # Optional. Add a Git branch name of a build to a build report kotlin.build.report.http.include_git_branch.name=true|false # Optional. Add compiler arguments to a build report # If a project contains many modules, its compiler arguments in the report can be very heavy and not that helpful kotlin.build.report.include_compiler_arguments=true|false
Ограничение на пользовательские значения
Для сбора статистики сканирований сборки отчёты о сборке Kotlin используют пользовательские значения Gradle. Данные в пользовательские значения могут записывать как вы, так и различные плагины Gradle. Количество пользовательских значений ограничено. Текущий максимум пользовательских значений см. в документации по плагину Build Scan.
В большом проекте таких пользовательских значений может быть довольно много. Если их количество превышает ограничение, в журналах появится следующее сообщение:
Maximum number of custom values (1,000) exceeded
Чтобы уменьшить количество пользовательских значений, создаваемых плагином Kotlin, можно использовать следующее свойство в gradle.properties:
kotlin.build.report.build_scan.custom_values_limit=500
Отключение сбора свойств проекта и системы
Журналы статистики сборки, отправляемые по HTTP, могут содержать некоторые свойства проекта и системы. Эти свойства могут влиять на поведение сборок, поэтому полезно записывать их в статистику сборки. В них могут храниться конфиденциальные данные, например пароли или полный путь к проекту.
Сбор этой статистики можно отключить, добавив свойство kotlin.build.report.http.verbose_environment в файл gradle.properties.
Что дальше?
Подробнее:
© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/gradle-compilation-and-caches.html