配置缓存通过缓存配置阶段的结果并在后续构建中复用,从而提高构建性能。

configuration cache 4

配置缓存基础

Gradle 构建生命周期包含三个阶段:初始化配置执行

  1. 初始化阶段确定构建的结构。

  2. 配置阶段评估需要完成的工作。

  3. 执行阶段执行该工作。

Gradle 的构建缓存长期以来通过重用之前构建的输出和尽可能并行化工作来优化执行阶段。

配置缓存建立在避免重复工作并行化的思想之上。启用后,如果影响构建配置(例如构建脚本)的任何内容都没有改变,配置缓存允许 Gradle 完全跳过配置阶段。此外,Gradle 还对任务执行应用了性能优化。

为此,Gradle 执行以下操作

阶段 缓存 避免重复工作 并行和性能

执行

构建缓存

使用任务输入和输出

使用 --parallel 并行运行独立任务

配置

配置缓存

使用构建逻辑和环境

并行运行任务(在同一项目内),优化内存等

配置缓存与构建缓存相似,但它们存储不同类型的数据

  • 构建缓存:存储构建的输出和中间文件(例如,任务输出、artifact 转换输出)。

  • 配置缓存:存储特定任务集的构建配置,捕获配置阶段的输出。

configuration cache 2

此功能默认不启用,并且有以下限制

自 Gradle 9.0 起,配置缓存是首选执行模式

避免重复工作

当启用配置缓存并为特定任务集运行 Gradle 时,例如 ./gradlew check,Gradle 会查找配置缓存条目。如果找到匹配的条目,Gradle 会重用它并完全跳过配置阶段。缓存命中对于避免配置工作至关重要。

配置缓存条目

缓存条目包含

  • 要运行的任务集

  • 它们的配置详细信息

  • 依赖信息

首次执行

configuration cache 1

首次运行一组任务时,没有缓存条目。Gradle 照常执行配置阶段

  1. 运行初始化脚本。

  2. 运行设置脚本,应用任何请求的设置插件。

  3. 如果有 buildSrc 项目,则配置并构建它。

  4. 运行构建脚本,应用任何请求的项目插件。如果插件来自包含的构建,Gradle 会首先构建它们。

  5. 计算任务图,执行延迟的配置操作。

然后,Gradle 将任务图的快照存储在配置缓存中以供将来使用。之后,Gradle 从缓存中加载任务图并继续执行任务。

后续运行

configuration cache 3

在后续执行相同任务时(例如,再次运行 ./gradlew check),Gradle 会

  • 完全跳过配置阶段。

  • 而是从配置缓存中加载任务图。

在使用缓存之前,Gradle 会验证是否没有构建配置输入发生更改。如果任何输入已更改,Gradle 会重新运行配置阶段并更新缓存。

构建配置输入

以下元素决定配置缓存条目是否有效

  1. Gradle 环境

    • GRADLE_USER_HOME

    • Gradle Daemon JVM

  2. 初始化脚本

  3. buildSrc 和包含的构建逻辑构建内容(构建脚本、源文件和中间构建输出)

  4. 构建和设置脚本,包括包含的脚本 (apply from: foo.gradle)

  5. Gradle 配置文件(版本目录、依赖验证文件、依赖锁定文件、gradle.properties 文件)

  6. 在配置时读取的文件内容

  7. 在配置时检查的文件系统状态(文件存在、目录内容等)

  8. 在配置时获得的自定义 ValueSource 值(这也包括内置提供者,如 providers.execproviders.fileContents)。

  9. 在配置阶段使用的系统属性

  10. 在配置阶段使用的环境变量

序列化

Gradle 使用优化的序列化机制来存储配置缓存条目。它会自动序列化包含简单状态或受支持类型的对象图。

虽然配置缓存序列化不依赖于 Java 序列化,但它理解它的一些功能。这可用于自定义序列化行为,但会产生性能损失,应避免使用。

性能改进

除了跳过配置阶段之外,配置缓存还通过以下方式提高性能

  • 并行任务执行:所有任务默认并行运行,受限于依赖约束。

  • 缓存依赖解析:依赖解析结果被存储和重用。

  • 优化内存使用:将任务图写入缓存后,Gradle 会从内存中丢弃配置和依赖解析状态,从而降低峰值堆使用量。

running help

IDE 支持

如果您在 gradle.properties 文件中启用并配置了配置缓存,当您的 IDE 将构建委托给 Gradle 时,它将自动启用。无需额外设置。

由于 gradle.properties 通常会被检入到版本控制中,因此以这种方式启用配置缓存将应用于整个团队。如果您只想在本地环境中启用它,则可以直接在 IDE 中配置它。

在 IDE 中同步项目不会从配置缓存中受益。只有通过 IDE 运行任务才会利用缓存。

基于 IntelliJ 的 IDE

在 IntelliJ IDEA 或 Android Studio 中,可以通过两种方式完成此操作:全局或按运行配置。

要为整个构建启用它,请转到 Run > Edit configurations…​。这将打开 IntelliJ IDEA 或 Android Studio 对话框以配置运行/调试配置。选择 Templates > Gradle 并将必要的系统属性添加到 VM options 字段。

例如,要启用配置缓存,将问题转换为警告,请添加以下内容

-Dorg.gradle.configuration-cache=true -Dorg.gradle.configuration-cache.problems=warn

您还可以选择仅为给定的运行配置启用它。在这种情况下,请保留 Templates > Gradle 配置不变,并根据需要编辑每个运行配置。

通过同时使用这些方法,您可以全局启用配置缓存,同时为某些运行配置禁用它,反之亦然。

您可以使用 gradle-idea-ext-plugin 从您的构建中配置 IntelliJ 运行配置。

这是仅为 IDE 启用配置缓存的好方法。

基于 Eclipse 的 IDE

在基于 Eclipse 的 IDE 中,您可以通过 Buildship 启用配置缓存,无论是全局还是按运行配置。

要全局启用它

  1. 转到 Preferences > Gradle

  2. 添加以下 JVM 参数

    • -Dorg.gradle.configuration-cache=true

    • -Dorg.gradle.configuration-cache.problems=warn

要为特定运行配置启用它

  1. 打开 Run Configurations…​.

  2. 选择所需的配置。

  3. 导航到 Project Settings,选中 Override project settings,并添加与 JVM arguments 相同的系统属性。

通过同时使用这些方法,您可以全局启用配置缓存,同时为某些运行配置禁用它,反之亦然。