この記事はand factory.inc Advent Calendar 2025 4日目の記事です。
前回の記事は @ticktakclock さんの https://qiita.com/ticktakclock/items/4eee84de17c7711000fd でした ![]()
Android プロジェクトを CI(Github Actions など)で回していると、「ローカルでは通るのに CI だけ落ちる」という現象がよく起こります。特に大規模化したプロジェクトでは、ビルド時に必要なメモリ量が増えるため、CI のメモリ不足が原因で落ちるケースが非常に多いです。
本記事では、そのような状況で役立つ CI 向けメモリチューニングのポイントを紹介します。
基本原則:必要メモリ量は「下限」と「上限」で考える
Android プロジェクトでは、次の関係が必ず成り立ちます。
プロジェクトが必要とするメモリ量 ≦ 実行環境(ローカル or CI)のスペック
たとえば、あるプロジェクトが安定ビルドに 10GB のメモリを必要とする場合は、
- Gradle 側で 10GB 以上使える設定を行う
- 実行するマシン(ローカル PC)は 16GB 以上を搭載している必要がある
という具合です。
CI でも考え方は同じです。
プロジェクトが必要とするメモリ設定 ≦ CI ランナーのスペック
この原則を意識するだけで、無駄に設定を迷ったり、原因不明のエラーに悩む時間を減らすことができます。
1. まずはローカルでビルドが通る状態にする
当たり前ですが、ローカルで安定してビルドできていないプロジェクトは、CIでも安定しません。
大規模プロジェクトでは、PC のメモリが 32GB あったとしても、Gradle の設定が不十分だとビルドは通りません。
そのため、まずは gradle.properties 側で必要量をしっかり指定しておくことが重要です。
例:筆者のプロジェクトでは以下のように設定しています。
org.gradle.jvmargs=-Xmx8g -XX:MaxMetaspaceSize=1g -Dkotlin.daemon.jvm.options=-Xmx8g
org.gradle.jvmargs …… Gradle Daemon のヒープ最大値
-Dkotlin.daemon.jvm.options=-Xmx8g …… Kotlin Daemon 用 JVM のヒープ最大値
この2つだけで16GBを指定しているので、他のプロセスなどを考慮すると実際は32GBくらいのPCがないと安定しないという設定です。
2. CI 環境のスペックを正しく把握する
次に、自分が利用している CI の環境・課金プラン・ランナーのスペックを把握しましょう。
これを知らないまま「とりあえず CI を回す」のは無謀です。
例:GitHub Actions の場合
-
デフォルトのプライベートリポジトリのランナー
- CPU: 2コア
- メモリ: 7GB
ローカルでは通るのに GitHub Actions では落ちる……というとき、原因はほぼ メモリ不足です。
ビルドに 10GB 必要なプロジェクトを 7GB の環境で動かすのは当然無理なので、次のような対策が必要になります。
- GitHub Actions で 「Large」ランナー(4コア / 16GB) に変更する
- あるいは Gradle 側で必要メモリ量を減らすチューニングを検討する
3. CI に合わせて JVM メモリを“制御する”
「Large ランナーにしても CI が落ちる」という場合、
プロジェクトの Gradle 設定が CI のメモリ上限を超えている可能性があります。
例:ランナーは 16GB なのに、gradle.properties で 16GB 以上を要求してしまうケース。
そこで、ローカルの設定はそのまま維持しつつ、
CI 上だけ JVM メモリ量を抑える テクニックがあります。
▼ ローカル(gradle.properties はそのまま)
org.gradle.jvmargs=-Xmx8g -XX:MaxMetaspaceSize=1g -Dkotlin.daemon.jvm.options=-Xmx8g
▼ CI(GitHub Actions)側だけ上書きする例
env:
GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx8192m -Dkotlin.daemon.jvm.options=-Xmx4g"
ポイント:
- Gradle は コマンドライン引数(GRADLE_OPTS)が
gradle.propertiesより優先 されます - CI だけ上書きすることで、ローカルの要求スペックを下げずに済む
- Kotlin Daemon 側を 4GB に抑えるなど、合計が CI の 16GB を超えないように調整する
※ ちなみに、筆者も最近まで知らなかったのですがKotlin Daemonの指定を何もしない場合、gradle.jvmargsのメモリ指定がそのままKotlin Daemonのメモリ指定となるようです。ハマりポイントとして、gradle.jvmargsを8GBに指定していて、ランナーが16GBなのだから通るはずだと思ってしまう点です。この場合実はKotlin Daemonも8GB指定となってしまうため合計16GB以上となってしまいます。
ただし、メモリを下げすぎると今度は CI 上でビルドが通らなくなるため、
プロジェクトに必要なメモリ量と、CI の上限スペックの“絶妙なバランス”を探る必要があります。
まとめ
本記事では、Android プロジェクトの CI において特に重要な「メモリ指定」の考え方と実践方法を紹介しました。
- 必要メモリ量は ローカル / CI のスペックより小さく
- CI では「ローカルの設定を上書きする」ことで安定化が可能
- GitHub Actions ではランナーのスペック選択が重要
- メモリは Android CI の安定化における“土台”となる部分
その他にも、並列ビルドの無効化、ライブラリの細かなオプション調整などのテクニックがありますが、
まずは メモリ設定の見直し が最重要です。
CI が不安定な方は、ぜひ一度メモリ周りを再点検してみてください。