Gradle(三) 守護進程

Gradle Daemon

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 對咱們用戶是徹底透明的。性能優化

爲何 Gradle Daemon 對提高構建的表現是很重要的

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 Daemon 功能

默認狀況下,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命令輕鬆地驗證守護進程是否已經中止。

FAQ

我怎麼禁用Gradle 守護進程?

這裏有兩種推薦的方法能夠禁用守護進程:

  • 經過環境變量: 添加標誌-Dorg.gradle.daemon=falseGRADLE_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小時以上的守護進程,因此沒必要擔憂手動清理它們。

  • idle:是指當前沒有執行構建或執行其餘有用工做的守護進程。
  • compatible:compatible daemon 進程是可以知足所請求的構建環境的要求的守護進程。用於執行構建的Java運行時是構建環境的一個示例方面。另外一個示例是構建運行時所需的JVM系統屬性集。

守護進程可能沒法知足所請求的構建環境的某些選項或者配置。若是守護進程與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會在每次構建時收集大量有關文件系統狀態的信息。在啓用監視文件系統時,守護進程能夠重用從上次構建中收集到的信息。這能夠爲增量構建節省大量時間,由於在兩個構建之間,文件系統的更改數量一般很低。

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息