Skip to content

Kotlin Gradleプラグインにおけるコンパイルとキャッシュ

このページでは、以下のトピックについて学ぶことができます。

インクリメンタルコンパイル

Kotlin Gradleプラグインはインクリメンタルコンパイルをサポートしており、Kotlin/JVMおよびKotlin/JSプロジェクトではデフォルトで有効になっています。 インクリメンタルコンパイルは、ビルド間のクラスパス内のファイルの変更を追跡し、これらの変更によって影響を受けるファイルのみがコンパイルされるようにします。 このアプローチは、Gradleのビルドキャッシュと連携し、コンパイル回避をサポートします。

Kotlin/JVMの場合、インクリメンタルコンパイルはクラスパスのスナップショットに依存しています。 これは、モジュールのAPI構造をキャプチャし、いつ再コンパイルが必要かを判断します。 全体のパイプラインを最適化するために、Kotlinコンパイラは2種類のクラスパススナップショットを使用します。

  • 詳細スナップショット (Fine-grained snapshots):プロパティや関数など、クラスメンバーに関する詳細情報を含みます。 メンバーレベルの変更が検出されると、Kotlinコンパイラは変更されたメンバーに依存するクラスのみを再コンパイルします。 パフォーマンスを維持するために、Kotlin GradleプラグインはGradleキャッシュ内の.jarファイルに対して粗粒度スナップショットを作成します。
  • 粗粒度スナップショット (Coarse-grained snapshots):クラスのABIハッシュのみを含みます。 ABIの一部が変更された場合、Kotlinコンパイラは変更されたクラスに依存するすべてのクラスを再コンパイルします。 これは、外部ライブラリのように頻繁に変更されないクラスに役立ちます。

NOTE

Kotlin/JSプロジェクトは、履歴ファイルに基づく異なるインクリメンタルコンパイルアプローチを使用します。

インクリメンタルコンパイルを無効にする方法はいくつかあります。

  • Kotlin/JVMではkotlin.incremental=falseを設定します。

  • Kotlin/JSプロジェクトではkotlin.incremental.js=falseを設定します。

  • コマンドラインパラメータとして-Pkotlin.incremental=falseまたは-Pkotlin.incremental.js=falseを使用します。

    このパラメータは、以降の各ビルドに追加する必要があります。

インクリメンタルコンパイルを無効にすると、ビルド後にインクリメンタルキャッシュが無効になります。最初のビルドは決してインクリメンタルではありません。

TIP

インクリメンタルコンパイルの問題は、エラー発生から数回後のビルドで初めて顕在化することがあります。ビルドレポートを使用して

変更とコンパイルの履歴を追跡してください。これは、再現可能なバグ報告の提供に役立ちます。

現在のインクリメンタルコンパイルのアプローチがどのように機能し、以前のアプローチと比較してどうかについて詳しく知るには、ブログ投稿をご覧ください。

Gradleビルドキャッシュのサポート

Kotlinプラグインは、Gradleビルドキャッシュを使用します。これは、将来のビルドで再利用するために ビルド出力を保存します。

すべてのKotlinタスクでキャッシュを無効にするには、システムプロパティkotlin.caching.enabledfalseに設定します(ビルドを引数-Dkotlin.caching.enabled=falseで実行します)。

Gradleコンフィグレーションキャッシュのサポート

Kotlinプラグインは、Gradleコンフィグレーションキャッシュを使用します。これは、以降のビルドで設定フェーズの結果を再利用することで、ビルドプロセスを高速化します。

コンフィグレーションキャッシュを有効にする方法については、Gradleドキュメントを参照してください。この機能を有効にすると、Kotlin Gradleプラグインは自動的にそれを使用し始めます。

KotlinデーモンとGradleでの使用方法

Kotlinデーモンは以下の機能を提供します。

  • Gradleデーモンと一緒に実行され、プロジェクトをコンパイルします。
  • IntelliJ IDEAの内蔵ビルドシステムでプロジェクトをコンパイルする場合、Gradleデーモンとは別に実行されます。

Kotlinデーモンは、Kotlinコンパイルタスクのいずれかがソースのコンパイルを開始するときに、Gradleの実行段階で起動します。 Kotlinデーモンは、Gradleデーモンと一緒に停止するか、Kotlinのコンパイルが2時間アイドル状態が続いた後に停止します。

Kotlinデーモンは、Gradleデーモンと同じJDKを使用します。

KotlinデーモンのJVM引数の設定

次のいずれかの方法で引数を設定すると、それ以前に設定された引数が上書きされます。

Gradleデーモン引数の継承

デフォルトでは、KotlinデーモンはGradleデーモンから特定の引数セットを継承しますが、Kotlinデーモンに直接指定されたJVM引数によってそれらを上書きします。例えば、gradle.propertiesファイルに以下のJVM引数を追加した場合:

none
org.gradle.jvmargs=-Xmx1500m -Xms500m -XX:MaxMetaspaceSize=1g

これらの引数はKotlinデーモンのJVM引数に追加されます。

none
-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

NOTE

KotlinデーモンのJVM引数に関するデフォルトの動作について詳しく知るには、KotlinデーモンのJVM引数に関する動作をご覧ください。

kotlin.daemon.jvm.optionsシステムプロパティ

GradleデーモンのJVM引数にkotlin.daemon.jvm.optionsシステムプロパティが含まれている場合、gradle.propertiesファイルでそれを使用します。

none
org.gradle.jvmargs=-Dkotlin.daemon.jvm.options=-Xmx1500m,Xms500m

引数を渡す際には、以下のルールに従ってください。

  • XmxXX:MaxMetaspaceSizeXX:ReservedCodeCacheSizeの引数のみ、前にハイフン-使用します
  • 引数はスペースを_入れずに_カンマ,で区切ります。スペースの後に続く引数はKotlinデーモンではなく、Gradleデーモンで使用されます。

DANGER

以下のすべての条件が満たされている場合、Gradleはこれらのプロパティを無視します。

  • GradleがJDK 1.9以上を使用している。

  • Gradleのバージョンが7.0から7.1.1(両端を含む)の間である。

  • GradleがKotlin DSLスクリプトをコンパイルしている。

  • Kotlinデーモンが実行されていない。

これを回避するには、Gradleをバージョン7.2(またはそれ以上)にアップグレードするか、次のセクションで説明するkotlin.daemon.jvmargsプロパティを使用してください。

kotlin.daemon.jvmargsプロパティ

gradle.propertiesファイルにkotlin.daemon.jvmargsプロパティを追加できます。

none
kotlin.daemon.jvmargs=-Xmx1500m -Xms500m

ここで、またはGradleのJVM引数でReservedCodeCacheSize引数を指定しない場合、Kotlin Gradleプラグインはデフォルト値の320mを適用することに注意してください。

none
-Xmx1500m -XX:ReservedCodeCacheSize=320m -Xms500m

kotlinエクステンション

kotlinエクステンションで引数を指定できます。

kotlin
kotlin {
    kotlinDaemonJvmArgs = listOf("-Xmx486m", "-Xms256m", "-XX:+UseParallelGC")
}
groovy
kotlin {
    kotlinDaemonJvmArgs = ["-Xmx486m", "-Xms256m", "-XX:+UseParallelGC"]
}

特定のタスク定義

特定のタスクの引数を指定できます。

kotlin
tasks.withType<CompileUsingKotlinDaemon>().configureEach {
    kotlinDaemonJvmArguments.set(listOf("-Xmx486m", "-Xms256m", "-XX:+UseParallelGC"))
}
groovy
tasks.withType(CompileUsingKotlinDaemon).configureEach { task ->
    task.kotlinDaemonJvmArguments = ["-Xmx1g", "-Xms512m"]
}

NOTE

この場合、タスク実行時に新しいKotlinデーモンインスタンスが起動する可能性があります。KotlinデーモンのJVM引数に関する動作について詳しく学びましょう。

KotlinデーモンのJVM引数に関する動作

KotlinデーモンのJVM引数を設定する際は、以下の点に注意してください。

  • 異なるサブプロジェクトやタスクが異なるJVM引数セットを持つ場合、複数のKotlinデーモンインスタンスが同時に実行されることが想定されます。
  • 新しいKotlinデーモンインスタンスは、Gradleが関連するコンパイルタスクを実行し、既存のKotlinデーモンが同じJVM引数セットを持たない場合にのみ起動します。 プロジェクトに多数のサブプロジェクトがあるとします。ほとんどのサブプロジェクトはKotlinデーモンのためのヒープメモリを少量しか必要としませんが、1つのモジュールは大量のヒープメモリを必要とします(ただし、コンパイルされることはめったにありません)。 この場合、そのモジュールには異なるJVM引数セットを提供すべきです。これにより、より大きなヒープサイズを持つKotlinデーモンは、この特定のモジュールを触る開発者に対してのみ起動します。

    NOTE

    もし、コンパイル要求を処理するのに十分なヒープサイズを持つKotlinデーモンがすでに実行されている場合、 他の要求されたJVM引数が異なっていても、新しいデーモンを起動する代わりにこのデーモンが再利用されます。

以下の引数が指定されていない場合、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以上の場合にのみ適用されます。

NOTE

KotlinデーモンのデフォルトJVM引数のリストは、バージョンによって異なる場合があります。実行中のJVMプロセス(Kotlinデーモンなど)の実際の`設定を確認するには、VisualVMのようなツールを使用できます。

以前のコンパイラへのロールバック

Kotlin 2.0.0以降、K2コンパイラがデフォルトで使用されます。

Kotlin 2.0.0以降で以前のコンパイラを使用するには、以下のいずれかを実行します。

  • build.gradle.ktsファイルで、言語バージョン1.9に設定します。

    または

  • 以下のコンパイラオプションを使用します:-language-version 1.9

K2コンパイラの利点について詳しくは、K2コンパイラ移行ガイドをご覧ください。

Kotlinコンパイラ実行戦略の定義

_Kotlinコンパイラ実行戦略_は、Kotlinコンパイラがどこで実行されるか、およびそれぞれの場合にインクリメンタルコンパイルがサポートされるかどうかを定義します。

コンパイラ実行戦略には3種類あります。

戦略Kotlinコンパイラが実行される場所インクリメンタルコンパイルその他の特徴と注意事項
デーモン (Daemon)独自のデーモンプロセス内はい_デフォルトかつ最速の戦略_です。異なるGradleデーモンや複数の並行コンパイル間で共有できます。
プロセス内 (In process)Gradleデーモンプロセス内いいえGradleデーモンとヒープを共有する場合があります。「プロセス内」実行戦略は「デーモン」実行戦略よりも_低速_です。各ワーカーは、コンパイルごとに個別のKotlinコンパイラのクラスローダーを作成します。
プロセス外 (Out of process)各コンパイルに対して個別のプロセス内いいえ最も低速な実行戦略です。「プロセス内」と同様ですが、さらにコンパイルごとにGradleワーカー内で個別のJavaプロセスを作成します。

Kotlinコンパイラ実行戦略を定義するには、以下のいずれかのプロパティを使用できます。

  • kotlin.compiler.execution.strategy Gradleプロパティ。
  • compilerExecutionStrategyコンパイルタスクプロパティ。

タスクプロパティcompilerExecutionStrategyは、Gradleプロパティkotlin.compiler.execution.strategyよりも優先されます。

kotlin.compiler.execution.strategyプロパティで利用可能な値は以下の通りです。

  1. daemon (デフォルト)
  2. in-process
  3. out-of-process

gradle.propertiesでGradleプロパティkotlin.compiler.execution.strategyを使用します。

none
kotlin.compiler.execution.strategy=out-of-process

compilerExecutionStrategyタスクプロパティで利用可能な値は以下の通りです。

  1. org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy.DAEMON (デフォルト)
  2. org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy.IN_PROCESS
  3. org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy.OUT_OF_PROCESS

ビルドスクリプトでタスクプロパティcompilerExecutionStrategyを使用します。

kotlin
import org.jetbrains.kotlin.gradle.tasks.CompileUsingKotlinDaemon
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy

// ...

tasks.withType<CompileUsingKotlinDaemon>().configureEach {
    compilerExecutionStrategy.set(KotlinCompilerExecutionStrategy.IN_PROCESS)
}
groovy
import org.jetbrains.kotlin.gradle.tasks.CompileUsingKotlinDaemon
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy

// ...

tasks.withType(CompileUsingKotlinDaemon)
    .configureEach {
        compilerExecutionStrategy = KotlinCompilerExecutionStrategy.IN_PROCESS
    }

Kotlinコンパイラのフォールバック戦略

Kotlinコンパイラのフォールバック戦略は、デーモンが何らかの理由で失敗した場合に、Kotlinデーモンの外でコンパイルを実行することです。 Gradleデーモンがオンの場合、コンパイラは「プロセス内」戦略を使用します。 Gradleデーモンがオフの場合、コンパイラは「プロセス外」戦略を使用します。

このフォールバックが発生すると、Gradleのビルド出力に以下の警告メッセージが表示されます。

none
Failed to compile with Kotlin daemon: java.lang.RuntimeException: Could not connect to Kotlin compile daemon
[exception stacktrace]
Using fallback strategy: Compile without Kotlin daemon
Try ./gradlew --stop if this issue persists.

しかし、別の戦略へのサイレントフォールバックは、大量のシステムリソースを消費したり、非決定的なビルドにつながる可能性があります。 これについては、このYouTrack issueで詳しく読むことができます。 これを避けるために、kotlin.daemon.useFallbackStrategyというGradleプロパティがあり、そのデフォルト値はtrueです。 この値がfalseの場合、デーモンの起動または通信に問題があるとビルドは失敗します。このプロパティをgradle.propertiesで宣言します。

none
kotlin.daemon.useFallbackStrategy=false

KotlinコンパイルタスクにはuseDaemonFallbackStrategyプロパティもあり、両方を使用する場合はGradleプロパティよりも優先されます。

kotlin
tasks {
    compileKotlin {
        useDaemonFallbackStrategy.set(false)
    }   
}
groovy
tasks.named("compileKotlin").configure {
    useDaemonFallbackStrategy = false
}

コンパイルを実行するためのメモリが不足している場合、ログにその旨のメッセージが表示されることがあります。

最新の言語バージョンの試用

Kotlin 2.0.0以降、最新の言語バージョンを試すには、gradle.propertiesファイルでkotlin.experimental.tryNextプロパティを設定します。このプロパティを使用すると、Kotlin GradleプラグインはKotlinバージョンのデフォルト値よりも1つ上の言語バージョンにインクリメントします。たとえば、Kotlin 2.0.0ではデフォルトの言語バージョンは2.0であるため、このプロパティは言語バージョン2.1を設定します。

または、以下のコマンドを実行することもできます。

shell
./gradlew assemble -Pkotlin.experimental.tryNext=true

ビルドレポートでは、各タスクのコンパイルに使用された言語バージョンを確認できます。

ビルドレポート

ビルドレポートには、異なるコンパイルフェーズの所要時間と、コンパイルがインクリメンタルでなかった理由が含まれています。 コンパイル時間が長すぎる場合や、同じプロジェクトなのに異なる場合に、パフォーマンスの問題を調査するためにビルドレポートを使用してください。

Kotlinビルドレポートは、単位が単一のGradleタスクであるGradleビルドスキャンよりも効率的にビルドパフォーマンスの問題を調査するのに役立ちます。

長時間のコンパイルのビルドレポートを分析することで解決できる一般的なケースが2つあります。

  • ビルドがインクリメンタルではなかった。原因を分析し、根本的な問題を修正します。
  • ビルドはインクリメンタルだったが、時間がかかりすぎた。ソースファイルの再編成を試みます — 大きなファイルを分割したり、個別のクラスを別のファイルに保存したり、大きなクラスをリファクタリングしたり、トップレベル関数を別のファイルで宣言したりなど。

ビルドレポートは、プロジェクトで使用されているKotlinバージョンも表示します。さらに、Kotlin 1.9.0以降、Gradleビルドスキャンでコードのコンパイルに使用されたコンパイラを確認できます。

ビルドレポートの読み方と、JetBrainsがビルドレポートをどのように使用しているかについて学びましょう。

ビルドレポートの有効化

ビルドレポートを有効にするには、gradle.propertiesでビルドレポートの出力先を宣言します。

none
kotlin.build.report.output=file

出力には以下の値とその組み合わせが利用可能です。

| オプション | 説明 Training:**

  • Students will explore various types of models, understand the characteristics of different models, and choose the appropriate models to solve various problems.
  • Students will learn how to deal with real-world data, including data collection, cleaning, preprocessing, and feature engineering, to improve the performance of models.
  • Students will learn how to evaluate model performance, choose appropriate evaluation metrics, and tune model parameters to achieve optimal performance.
  • Students will understand the limitations of models and the importance of interpretability and fairness, and learn how to address these issues.

Prerequisites

  • Familiarity with Python programming.
  • Basic understanding of linear algebra, calculus, and probability.

Instructor

[Instructor Name]

Course Outline

Week 1: Introduction to Machine Learning

  • What is Machine Learning?
  • Types of Machine Learning (Supervised, Unsupervised, Reinforcement Learning)
  • Applications of Machine Learning
  • Machine Learning Workflow
  • Setting up your Development Environment (Python, scikit-learn, pandas, numpy, matplotlib, seaborn)

Week 2: Data Preprocessing and Feature Engineering

  • Data Collection and Loading
  • Handling Missing Values
  • Handling Categorical Data
  • Feature Scaling (Normalization, Standardization)
  • Feature Engineering Techniques (Polynomial Features, Interaction Terms, One-Hot Encoding)
  • Dimensionality Reduction (PCA, t-SNE)

Week 3: Supervised Learning - Regression

  • Introduction to Regression
  • Linear Regression (Simple, Multiple)
  • Polynomial Regression
  • Ridge, Lasso, and Elastic Net Regression
  • Support Vector Regression (SVR)
  • Decision Tree Regression
  • Ensemble Methods for Regression (Random Forest Regressor, Gradient Boosting Regressor)
  • Evaluation Metrics for Regression (MAE, MSE, RMSE, R-squared)

Week 4: Supervised Learning - Classification

  • Introduction to Classification
  • Logistic Regression
  • K-Nearest Neighbors (KNN)
  • Support Vector Machines (SVM)
  • Decision Tree Classifier
  • Ensemble Methods for Classification (Random Forest Classifier, Gradient Boosting Classifier, AdaBoost)
  • Evaluation Metrics for Classification (Accuracy, Precision, Recall, F1-score, ROC-AUC)
  • Confusion Matrix and Classification Report

Week 5: Unsupervised Learning - Clustering and Association Rules

  • Introduction to Unsupervised Learning
  • Clustering Algorithms (K-Means, Hierarchical Clustering, DBSCAN)
  • Evaluating Clustering Performance (Silhouette Score)
  • Introduction to Association Rule Learning
  • Apriori Algorithm

Week 6: Model Evaluation and Hyperparameter Tuning

  • Cross-validation (K-Fold, Stratified K-Fold)
  • Bias-Variance Trade-off
  • Overfitting and Underfitting
  • Hyperparameter Tuning Techniques (Grid Search, Random Search, Bayesian Optimization)
  • Saving and Loading Models

Week 7: Introduction to Deep Learning and Neural Networks

  • Introduction to Deep Learning
  • Perceptron and Multilayer Perceptron (MLP)
  • Activation Functions (ReLU, Sigmoid, Tanh)
  • Loss Functions and Optimizers
  • Backpropagation
  • Building a Simple Neural Network with Keras/TensorFlow

Week 8: Advanced Topics and Model Deployment

  • Model Interpretability (LIME, SHAP)
  • Fairness in Machine Learning
  • Introduction to MLOps
  • Model Deployment Strategies (Flask, Docker)
  • Ethics in AI
  • Case Studies and Project Work

Grading

  • Homework Assignments: 40%
  • Midterm Project: 30%
  • Final Project: 30%

Contact Information

For any questions, please contact [Instructor Email Address].


Note: This course outline is subject to change based on the pace and needs of the students.