守护进程是作为后台进程运行而不是在交互式用户的直接控制下运行的计算机程序。

Gradle 在 Java 虚拟机 (JVM) 上运行,并使用多个支持库,初始化时间很长。初创公司可能会很慢。 Gradle守护进程解决了这个问题。

Gradle 守护进程是一个长期存在的后台进程,可以减少运行构建所需的时间。

Gradle 守护进程通过以下方式减少构建时间:

了解守护进程

Gradle JVM 客户端发送 Daemon 构建信息,例如命令行参数、项目目录和环境变量,以便它可以运行构建。 Wrapper负责解决依赖关系、执行构建脚本、创建和运行任务;完成后,它会将输出发送给客户端。客户端和守护进程之间的通信通过本地套接字连接进行。

守护进程使用 JVM 的默认最小堆大小。

如果请求的构建环境未指定最大堆大小,则守护程序最多使用 512MB 堆。 512MB 对于大多数构建来说已经足够了。具有数百个子项目、配置和源代码的较大构建可能会受益于较大的堆大小。

检查守护进程状态

要获取正在运行的守护进程及其状态的列表,请使用以下--status命令:

$ gradle --status
   PID STATUS   INFO
 28486 IDLE     7.5
 34247 BUSY     7.5

目前,给定的 Gradle 版本只能连接到相同版本的 Daemon。这意味着状态输出仅显示生成的守护进程运行与当前项目相同版本的 Gradle。

查找守护进程

如果您已经安装了 Java 开发工具包 (JDK),则可以使用以下命令查看实时守护进程jps

$ jps
33920 Jps
27171 GradleDaemon
22792

Live Daemons 出现在名称下方GradleDaemon。由于此命令使用 JDK,因此您可以查看运行任何版本的 Gradle 的守护进程。

启用守护进程

从 Gradle 3.0 开始,Gradle 默认启用 Daemon。如果您的项目不使用守护进程,则可以--daemon在运行构建时使用以下标志为单个构建启用它:

$ gradle <task> --daemon

此标志会覆盖在项目或用户gradle.properties文件中禁用守护程序的任何设置。

要在较旧的 Gradle 版本中默认启用守护程序,请将以下设置添加到gradle.properties项目根目录或 Gradle 用户主页中的文件中(GRADLE_USER_HOME

gradle.properties
org.gradle.daemon=true

禁用守护进程

您可以通过多种方式禁用守护进程,但有一些重要的注意事项:

一次性守护进程

如果客户端进程的 JVM 参数与构建所需的不匹配,则会创建一次性守护进程(一次性 JVM)。这意味着构建需要守护进程,因此它被创建、使用,然后在构建结束时停止。

无守护进程

如果JAVA_OPTSGRADLE_OPTS匹配org.gradle.jvmargs,则根本不会使用守护程序,因为构建发生在客户端 JVM 中。

禁用构建

要禁用单个构建的守护进程,请--no-daemon在运行构建时传递该标志:

$ gradle <task> --no-daemon

此标志会覆盖在项目中启用守护程序的任何设置(包括gradle.properties文件)。

为项目禁用

要为项目的所有构建禁用守护程序,请添加org.gradle.daemon=falsegradle.properties项目根目录中的文件。

为用户禁用

在 Windows 上,此命令会禁用当前用户的守护进程:

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

在类 UNIX 操作系统上,以下 Bash shell 命令会禁用当前用户的守护进程:

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

全局禁用

有两种建议的方法可以在环境中全局禁用守护程序:

  • 添加org.gradle.daemon=false到/gradle.properties` 文件$GRADLE_USER_HOME

  • 将标志添加-Dorg.gradle.daemon=falseGRADLE_OPTS环境变量中

如果您想完全禁用守护进程而不是简单地调用一次性守护进程,请不要忘记确保您的 JVM 参数和GRADLE_OPTS/匹配。JAVA_OPTS

停止守护进程

在故障排除或调试故障时停止守护程序会很有帮助。

如果出现以下任一情况,守护进程将自动停止:

  • 可用系统内存不足

  • 守护进程已空闲 3 小时

要停止运行守护进程,请使用以下命令:

$ gradle --stop

这将终止使用用于执行命令的同一版本的 Gradle 启动的所有守护进程进程。

您还可以使用操作系统手动终止守护程序。要查找所有守护进程的 PID(无论 Gradle 版本如何),请参阅查找守护进程

工具和 IDE

IDE 和其他与 Gradle 集成的工具使用的Gradle Tooling API始终使用Gradle Daemon 来执行构建。如果您从 IDE 中执行 Gradle 构建,则您已经使用了 Gradle Daemon。无需为您的环境启用它。

持续集成

我们建议对开发人员计算机和持续集成 (CI) 服务器使用守护程序。

兼容性

如果不存在空闲或兼容的守护进程,Gradle 会启动一个新的守护进程。

以下值决定兼容性:

  • 请求的构建环境,包括以下内容:

    • Java版本

    • JVM 属性

    • JVM 属性

  • 摇篮版本

兼容性基于这些值的精确匹配。例如:

  • 如果守护程序可用于 Java 8 运行时,但请求的构建环境调用 Java 10,则该守护程序不兼容。

  • 如果守护进程可运行 Gradle 7.0,但当前构建使用 Gradle 7.4,则该守护进程不兼容。

Java 运行时的某些属性是不可变的:一旦 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 属性也是不可变的:

  • 最大堆大小(-XmxJVM 参数)

  • 最小堆大小(-XmsJVM 参数)

  • 启动类路径(-Xbootclasspath参数)

  • “断言”状态(-ea参数)

如果任何这些特性和属性的请求构建环境要求与守护程序的 JVM 要求不同,则守护程序不兼容。

有关构建环境的更多信息,请参阅构建环境文档

性能影响

当您重复构建同一项目时,守护进程可以将构建时间缩短 15-75%。

要了解守护进程对您的构建的影响,您可以使用 来分析您的构建--profile

在构建之间,守护进程空闲地等待下一个构建。因此,您的机器只会在多次构建时将 Gradle 加载到内存中一次,而不是每次构建一次。这是一项重大的性能优化。

运行时代码优化

JVM 通过运行时代码优化获得了显着的性能:在代码运行时应用优化。

OpenJDK 的 Hotspot 等 JVM 实现会在执行过程中逐步优化代码。因此,纯粹由于此优化过程,后续构建可以更快。

使用守护进程,项目的第 1和第 10构建之间的感知构建时间可能会大幅缩短。

内存缓存

守护进程支持跨构建的内存缓存。这包括插件和构建脚本的类。

同样,守护进程维护构建数据的内存缓存,例如增量构建的任务输入和输出的哈希值。

性能监控

Gradle 主动监视堆使用情况以检测守护进程中的内存泄漏。

当内存泄漏耗尽可用堆空间时,守护进程:

  1. 完成当前正在运行的构建。

  2. 在运行下一个构建之前重新启动。

Gradle 默认启用此监控。

要禁用此监视,请将org.gradle.daemon.performance.enable-monitoringDaemon 选项设置为false

您可以使用以下命令在命令行上执行此操作:

$ gradle <task> -Dorg.gradle.daemon.performance.enable-monitoring=false

gradle.properties或者您可以在项目根目录或 GRADLE_USER_HOME(Gradle 用户主页)的文件中配置该属性:

gradle.properties
org.gradle.daemon.performance.enable-monitoring=false