守护进程是作为后台进程运行而不是在交互式用户的直接控制下运行的计算机程序。
Gradle 在 Java 虚拟机 (JVM) 上运行,并使用多个支持库,初始化时间很长。初创公司可能会很慢。 Gradle守护进程解决了这个问题。
Gradle 守护进程是一个长期存在的后台进程,可以减少运行构建所需的时间。
Gradle 守护进程通过以下方式减少构建时间:
-
跨构建缓存项目信息
-
在后台运行,因此每个 Gradle 构建都不必等待 JVM 启动
-
受益于 JVM 中的持续运行时优化
-
在运行构建之前观察文件系统以准确计算需要重建的内容
了解守护进程
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
:
org.gradle.daemon=true
禁用守护进程
您可以通过多种方式禁用守护进程,但有一些重要的注意事项:
- 一次性守护进程
-
如果客户端进程的 JVM 参数与构建所需的不匹配,则会创建一次性守护进程(一次性 JVM)。这意味着构建需要守护进程,因此它被创建、使用,然后在构建结束时停止。
- 无守护进程
-
如果
JAVA_OPTS
和GRADLE_OPTS
匹配org.gradle.jvmargs
,则根本不会使用守护程序,因为构建发生在客户端 JVM 中。
禁用构建
要禁用单个构建的守护进程,请--no-daemon
在运行构建时传递该标志:
$ gradle <task> --no-daemon
此标志会覆盖在项目中启用守护程序的任何设置(包括gradle.properties
文件)。
为项目禁用
要为项目的所有构建禁用守护程序,请添加org.gradle.daemon=false
到gradle.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=false
到GRADLE_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 属性也是不可变的:
-
最大堆大小(
-Xmx
JVM 参数) -
最小堆大小(
-Xms
JVM 参数) -
启动类路径(
-Xbootclasspath
参数) -
“断言”状态(
-ea
参数)
如果任何这些特性和属性的请求构建环境要求与守护程序的 JVM 要求不同,则守护程序不兼容。
有关构建环境的更多信息,请参阅构建环境文档。 |
性能影响
当您重复构建同一项目时,守护进程可以将构建时间缩短 15-75%。
要了解守护进程对您的构建的影响,您可以使用 来分析您的构建--profile 。
|
在构建之间,守护进程空闲地等待下一个构建。因此,您的机器只会在多次构建时将 Gradle 加载到内存中一次,而不是每次构建一次。这是一项重大的性能优化。
运行时代码优化
JVM 通过运行时代码优化获得了显着的性能:在代码运行时应用优化。
OpenJDK 的 Hotspot 等 JVM 实现会在执行过程中逐步优化代码。因此,纯粹由于此优化过程,后续构建可以更快。
使用守护进程,项目的第 1次和第 10次构建之间的感知构建时间可能会大幅缩短。
性能监控
Gradle 主动监视堆使用情况以检测守护进程中的内存泄漏。
当内存泄漏耗尽可用堆空间时,守护进程:
-
完成当前正在运行的构建。
-
在运行下一个构建之前重新启动。
Gradle 默认启用此监控。
要禁用此监视,请将org.gradle.daemon.performance.enable-monitoring
Daemon 选项设置为false
。
您可以使用以下命令在命令行上执行此操作:
$ gradle <task> -Dorg.gradle.daemon.performance.enable-monitoring=false
gradle.properties
或者您可以在项目根目录或 GRADLE_USER_HOME(Gradle 用户主页)的文件中配置该属性:
org.gradle.daemon.performance.enable-monitoring=false