Daemon 是一種電腦程式,它以背景程式的形式執行,而不是在互動使用者的直接控制之下。

Gradle 在 Java 虛擬機器 (JVM) 上執行,並使用數個支援函式庫,其初始化時間非同小可。啟動可能會很慢。Gradle Daemon 解決了這個問題。

Gradle Daemon 是一個長駐的背景程式,可以減少執行建置所需的時間。

Gradle Daemon 透過下列方式減少建置時間

  • 快取跨建置的專案資訊

  • 在背景執行,因此每個 Gradle 建置不必等待 JVM 啟動

  • 受益於 JVM 中持續的執行時間最佳化

  • 觀察檔案系統,以在執行建置之前精確計算需要重新建置的內容

了解 Daemon

Gradle JVM 用戶端會將建置資訊(例如命令列引數、專案目錄和環境變數)傳送給 Daemon,以便它可以執行建置。Wrapper 負責解析相依性、執行建置指令碼、建立和執行任務;完成後,它會將輸出傳送給用戶端。用戶端和 Daemon 之間的通訊透過本機 socket 連線進行。

Daemon 使用 JVM 的預設最小堆積大小。

如果請求的建置環境未指定最大堆積大小,Daemon 會使用高達 512MB 的堆積。512MB 對於大多數建置而言已足夠。具有數百個子專案、組態和原始碼的大型建置可能會受益於更大的堆積大小。

檢查守護程序狀態

若要取得正在執行的守護程序清單及其狀態,請使用 --status 指令

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

目前,指定的 Gradle 版本只能連線至相同版本的守護程序。這表示狀態輸出只會顯示使用與目前專案相同的 Gradle 版本所衍生的守護程序。

尋找守護程序

如果您已安裝 Java Development Kit (JDK),您可以使用 jps 指令查看即時守護程序。

$ jps
33920 Jps
27171 GradleDaemon
22792

即時守護程序會顯示在 GradleDaemon 名稱下方。由於此指令使用 JDK,因此您可以查看執行任何 Gradle 版本的守護程序。

啟用守護程序

自 Gradle 3.0 起,Gradle 預設啟用守護程序。如果您的專案未使用守護程序,您可以在執行建置時使用 --daemon 旗標為單一建置啟用守護程序

$ gradle <task> --daemon

此旗標會覆寫專案或使用者 gradle.properties 檔案中任何停用守護程序的設定。

若要在舊版 Gradle 中預設啟用守護程序,請將下列設定新增至專案根目錄或 Gradle 使用者主目錄 (GRADLE_USER_HOME) 中的 gradle.properties 檔案

gradle.properties
org.gradle.daemon=true

停用守護程序

您可以使用多種方式停用守護程序,但有重要的考量因素

單次使用守護程序

如果客戶端程序的 JVM 引數與建置需求不符,則會建立單次使用的守護程序 (一次性 JVM)。這表示建置需要守護程序,因此會在建置開始時建立守護程序,並在建置結束時使用並停止守護程序。

無守護程序

如果 JAVA_OPTSGRADLE_OPTSorg.gradle.jvmargs 相符,則根本不會使用守護程序,因為建置會在客戶端 JVM 中執行。

停用單一建置

若要停用單一建置的守護程序,請在執行建置時傳遞 --no-daemon 旗標

$ gradle <task> --no-daemon

此旗標會覆寫專案中任何啟用守護程序的設定,包括 gradle.properties 檔案。

停用單一專案

若要停用專案所有建置的守護程序,請將 org.gradle.daemon=false 新增至專案根目錄中的 gradle.properties 檔案。

針對使用者停用

在 Windows 上,此指令會針對目前使用者停用 Daemon

(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 指令會針對目前使用者停用 Daemon

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

全面停用

建議使用兩種方法在環境中全面停用 Daemon

  • org.gradle.daemon=false 新增至 $GRADLE_USER_HOME/gradle.properties` 檔案

  • 將旗標 -Dorg.gradle.daemon=false 新增至 GRADLE_OPTS 環境變數

如果您想要完全停用 Daemon,而不是只呼叫一次性 Daemon,請務必確認您的 JVM 引數和 GRADLE_OPTS / JAVA_OPTS 相符。

停止 Daemon

在進行故障排除或除錯時,停止 Daemon 可能會有幫助。

Daemon 會在符合下列任一條件時自動停止

  • 可用系統記憶體不足

  • Daemon 已閒置 3 小時

若要停止正在執行的 Daemon 程序,請使用下列指令

$ gradle --stop

此指令會終止所有使用與執行指令相同的 Gradle 版本啟動的 Daemon 程序。

您也可以使用作業系統手動終止 Daemon。若要找出所有 Daemon 的 PID,不論 Gradle 版本為何,請參閱 尋找 Daemon

工具和 IDE

Gradle Tooling API 由 IDE 和其他工具用於與 Gradle 整合,永遠會使用 Gradle Daemon 執行建置。如果您從 IDE 內執行 Gradle 建置,您已經在使用 Gradle Daemon。不需要為您的環境啟用它。

持續整合

我們建議在開發人員電腦和持續整合 (CI) 伺服器上使用 Daemon。

相容性

如果沒有閒置或相容的 Daemon,Gradle 會啟動新的 Daemon。

下列數值會決定相容性

  • 要求的建置環境,包括下列

    • Java 版本

    • JVM 屬性

    • JVM 屬性

  • Gradle 版本

相容性基於這些值的完全比對。例如

  • 如果 Daemon 可用於 Java 8 執行時期,但要求的建置環境呼叫 Java 10,則 Daemon 不相容。

  • 如果 Daemon 可用於執行 Gradle 7.0,但目前的建置使用 Gradle 7.4,則 Daemon 不相容。

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 引數)

如果這些屬性和屬性中任何一個的要求建置環境需求與 Daemon 的 JVM 需求不同,則 Daemon 不相容。

如需建置環境的更多資訊,請參閱建置環境文件

效能影響

重複建置同一個專案時,Daemon 可將建置時間減少 15-75%。

如需了解 Daemon 對建置的影響,您可以使用 --profile 分析建置。

在建置之間,Daemon 會閒置等待下一個建置。因此,您的機器只會將 Gradle 載入記憶體一次以進行多個建置,而不是每個建置一次。這是顯著的效能最佳化。

執行時期程式碼最佳化

JVM 從執行時期程式碼最佳化獲得顯著效能:在程式碼執行時套用的最佳化。

OpenJDK 的 Hotspot 等 JVM 實作會在執行期間逐步最佳化程式碼。因此,後續建置可能會因為這個最佳化程序而加快。

使用 Daemon,專案第 1 和第 10 建置之間的感知建置時間可能會大幅縮短。

記憶體快取

Daemon 能在建置之間啟用記憶體快取。這包括外掛程式和建置指令碼的類別。

類似地,Daemon 會維護建置資料的記憶體快取,例如增量建置中任務輸入和輸出的雜湊。

效能監控

Gradle 會主動監控堆積使用情況,以偵測 Daemon 中的記憶體外洩。

當記憶體外洩耗盡可用堆積空間時,Daemon 會

  1. 完成目前執行的建置。

  2. 在執行下一個建置之前重新啟動。

Gradle 預設啟用此監控。

若要停用此監控,請將 org.gradle.daemon.performance.enable-monitoring Daemon 選項設定為 false

您可以在命令列中使用下列命令執行此動作

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

或者,您可以在專案根目錄或 GRADLE_USER_HOME (Gradle 使用者家目錄) 中的 gradle.properties 檔案中設定屬性

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