Daemon process 的定义:java
A daemon is a computer program that runs as a background process, rather than being under the direct control of an interactive user.web
————Wikipediawindows
我帮你们翻译过来就是:守护进程是做为后台进程运行的计算机程序,不受交互用户的直接控制。 若是你们对 Java 的线程熟悉的话,确定知道 Java 的线程也有一个 daomon 的参数,能够将这个线程设置为守护线程,这里的 守护线程的概念和上面的维基百科里的概念同样,运行在后台,不直接处理用户交互逻辑。关于Daemon 的概念就先介绍到这里。缓存
你们都知道 Gradle 是运行在 Java 虚拟机上的而且它须要的几个support libraries 都须要必定的初始化时间,因此 Gradle 的初始化是须要必定的时间的。解决这个问题的方法就是 Gradle Daemon,守护进程:一个长时间运行在后台的进程,避免频繁的初始化。而且 Gradle 会将 Project data 缓存在内存中,加快构建速度。使用Gradle Daemon 是没有任何反作用的,而且咱们能够很是简单的使用它,不须要任何成本,Gradle Daomen 对咱们用户是彻底透明的。性能优化
Daemon 是一个长生命周期的进程,这不只仅能够避免每次启动构建时的初始化所带来的资源消耗,并且能够缓存 project、task、output、files等数据在内存中。
理由很简单:经过重用之前构建的计算结果来提升构建速度。而且这样作的好处是很是显著的:咱们得出的结论是在后续的构建中构建的时间一般能够减小15-75%。咱们建议使用——profile
来分析你的构建,了解Gradle守护进程对构建的影响有多大。
在 Gradle3.0 以后 Gradle Daemon 是默认开启的服务器
使用--status
来查看守护进程的状态markdown
./gradlew --status
gradle --status
复制代码
这是一个例子:工具
PID VERSION STATUS
28411 3.0 IDLE
34247 3.0 BUSY
复制代码
须要注意的是这里只会显示与被调用 Gradle 的同版本的守护进程,而不会显示其余版本的进程。在将来 Gradle 可能会接触这一个限制,并将现实全部版本的运行中的守护进程。性能
默认状况下,Gradle守护进程是启用的,咱们建议始终启用它。你能够经过命令行选项——no-daemon
禁用Gradle守护进程,或者添加org.gradle。daemon=false
配置在 gradle.properties
文件中。
为了知足构建所需的JVM选项,Gradle一般会为构建生成一个单独的进程,即便守护进程的选项被禁用。 若是守护进程的选项被禁用,那么为了知足构建所需的JVM选项,Gradle一般会在每次构建的时候建立新的单独的进程。开发工具
Note: 无论是哪个Gradle版本,在开启守护进程选项后,Gradle的构建速度都会有很大的提高
在 Gradle 3.0 后,守护进程默认是开启的,不管是开发机仍是服务器,咱们都推荐使用守护进程。不过若是咱们以为在服务器上进行CI流程时,开启守护进程会对构建会产生不稳定因素,那么咱们能够关闭守护进程的选项。由于每次构建都会建立新的进程,
如上所述,守护进程是一个后台进程。不过,您没必要担忧在您的机器上构建Gradle进程的内存使用状况。每一个守护进程都监控本身的内存使用状况,并将其与系统总内存进行比较,当可用的系统内存较低时,守护进程将在空闲时中止自身。若是你想显式地中止运行守护进程,只要使用gradle——stop命令便可。
gradle --stop
复制代码
这将终止全部使用同一个版本的Gradle启动的守护进程。若是已经安装了Java开发工具包(JDK),那么您能够经过运行jps命令轻松地验证守护进程是否已经中止。
这里有两种推荐的方法能够禁用守护进程:
-Dorg.gradle.daemon=false
到GRADLE_OPTS
环境变量build.properties
文件: 添加org.gradledaemon=false
到«GRADLE_USER_HOME»/gradle.properties
文件中这两种方法都有相同的效果。用哪种取决于我的喜爱。不过咱们大多数开发者选择第二个选项,经过向 build.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-like:
mkdir -p ~/.gradle && echo "org.gradle.daemon=false" >> ~/.gradle/gradle.properties
复制代码
一旦在构建环境中上述种方式禁用了守护进程,Gradle守护进程将不会被启动,除非使用——Daemon选项
显式地请求。
当使用Gradle命令行时,——daemon
和——no-daemon
命令行选项能够启用或禁用单次构建调用的守护进程。在考虑构建环境时,这些命令行选项具备最高的优先级。一般,为环境启用守护进程更方便,这样全部构建都使用守护进程,而不须要记住提供——Daemon
选项。
Gradle建立一个新的守护进程,而不是使用一个已经在运行的守护进程的几个基本规则是,若是没有空闲或兼容的守护进程,Gradle将启动一个新的守护进程。Gradle会杀死任何闲置3小时以上的守护进程,因此没必要担忧手动清理它们。
守护进程可能没法知足所请求的构建环境的某些选项或者配置。若是守护进程与Java 8运行时一块儿运行,可是所请求的环境调用Java 10,那么守护进程不兼容,必须启动另外一个守护进程。并且,一旦JVM启动,Java运行时的某些属性就不能更改。例如,不能更改运行中的JVM的内存分配(例如-Xmx1024m)、默认文本编码、默认区域设置等。
如下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属性实际上也是不可变的。为了使守护进程兼容,被请求的构建环境和守护进程的环境的相应属性必须彻底匹配。
The maximum heap size (i.e. the -Xmx JVM argument)
The minimum heap size (i.e. the -Xms JVM argument)
The boot classpath (i.e. the -Xbootclasspath argument)
The “assertion” status (i.e. the -ea argument)
在使用不一样Gradle版本时同时处理多个Gradle项目也是拥有多个运行守护进程的常见缘由。
若是所请求的构建环境没有指定最大堆大小,守护进程将使用最多512MB的堆。它将使用JVM的默认最小堆大小。512MB对于大多数构建来讲已经足够了。带有数百个子项目、大量配置和源代码的大型构建可能须要更多内存,或者性能更好。
要增长守护进程可使用的内存量,能够为构建环境指定适当的标志位或者选项
守护进程将在3小时或更短的时间内自动终止。若是你想在此以前中止一个守护进程,你能够经过你的操做系统或者运行gradle --stop
命令来终止这个进程。——stop
开关会致使Gradle请求全部正在运行的守护进程(与运行该命令所用的Gradle版本相同)自行终止。
Gradle 团队已经将大量的工程工做投入到守护进程的开发中,使守护进程在平常开发中健壮、透明。可是,守护进程偶尔也会损坏或出现问题。Gradle构建能够执行多种源代码的任意代码。虽然Gradle自己是为守护进程设计的,而且通过了大量的测试,可是用户构建脚本和第三方插件可能会经过诸如内存泄漏或全局状态破坏等缺陷破坏守护进程。
运行没有正确释放资源的构建也可能破坏守护进程(以及通常的构建环境)的稳定。在使用微软Windows系统时,这是一个特别尖锐的问题,由于它不太能容忍程序在读取或写入文件后没法关闭文件。
Gradle会主动监控堆的使用状况,并尝试检测什么时候泄漏开始耗尽守护进程中的可用堆空间。当它检测到一个问题时,Gradle守护进程将完成当前正在运行的构建,并在下一次构建时主动重启该守护进程。这种监视在默认状况下是启用的,可是能够经过设置org.gradle.daemon.performance.enable-monitoring
为false来禁用。
若是怀疑守护进程变得不稳定,能够简单地杀死它。回想一下,能够为构建指定——no-daemon开关,以防止使用守护进程。这对于诊断这个守护进程是不是问题的罪魁祸首是颇有用的。
Gradle守护进程是一个长期存在的进程。在构建期间,它会空闲地等待下一次构建。这有一个明显的好处,即在屡次构建时只须要将Gradle加载到内存中一次,而不是每次构建时加载一次。这自己就是一个显著的性能优化,但它还不止于此。
现代JVM性能的一个重要部分是运行时代码优化。例如,HotSpot (Oracle提供的JVM实现,用做OpenJDK的基础)会在代码运行时对其进行优化。优化是渐进的,而不是瞬间的。也就是说,代码会在执行过程当中逐步优化,这意味着后续的构建会由于这个优化过程而变得更快。HotSpot的实验代表,须要5到10个构建才能实现稳定的优化。对于一个守护进程,第一次构建和第10次构建在构建时间上的差别是很是显著的。
这个守护进程还容许不一样构建之间进行更有效的内存缓存。例如,构建所需的类(例如插件、构建脚本)能够在构建之间保存在内存中。相似地,Gradle能够维护构建数据的内存缓存,好比任务输入和输出的散列,用于增量构建。
为了检测文件系统的变化,并计算须要从新构建的内容,Gradle会在每次构建时收集大量有关文件系统状态的信息。在启用监视文件系统时,守护进程能够重用从上次构建中收集到的信息。这能够为增量构建节省大量时间,由于在两个构建之间,文件系统的更改数量一般很低。