CLOVER🍀

That was when it all began.

Gradle Daemonを使う

昨日はGradleをちょっと使ってみたわけですが、元がGroovyだからかどうかはわかりませんけど、とにかく重い印象があります。やっぱり、こういうのって1回きりの使い捨てより、常駐型でないと厳しいですよね。

というわけで、ここでGradleが用意しているのがDaemonです。
http://www.gradle.org/docs/current/userguide/gradle_daemon.html
http://gradle.monochromeroad.com/docs/userguide/gradle_daemon.html

まあ、文章中に「experimental」と書かれているように、まだ試験的サポートのようですが。

とはいえ、効果は明らかにあるようなので、使っていってみましょう。今回使うGradleプロジェクトのスケープゴートは、最初に用意したJavaの「Hello World」プロジェクトです。

こんなやつですね。

public class HelloGradle {
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}

Gradle Daemonを使用する

けっこう簡単で、gradleコマンドの引数に「--daemon」を付けるだけです。

$ gradle --daemon run
:compileJava
:processResources UP-TO-DATE
:classes
:run
Hello World

BUILD SUCCESSFUL

Total time: 8.931 secs

この時、バックグラウンドで

org.gradle.launcher.daemon.bootstrap.GradleDaemon

というMainクラス名でJavaプロセスが起動していることが確認できます。psなどで見るとよいでしょう。

ここで、「Hello World」を「Hello Gradle」に変えて実行してみます。

$ gradle --daemon run
:compileJava
:processResources UP-TO-DATE
:classes
:run
Hello Gradle

BUILD SUCCESSFUL

Total time: 1.562 secs

初回は9秒かかっていたものが、一気に2秒弱まで短くなりましたね。なお、Daemonなしで同じ操作をすると、両方とも7秒程度の実行時間を要しました。

かなり高速になっていることが確認できます。なかなか便利ですね。

が、残念ながらScalaにはあまり効果はありませんでした…Groovyに対して適用した場合も、Javaよりは速度が落ちます。将来的にはGroovyやScalaのコンパイラの起動を維持したいと言っているので、今は仕方がないのでしょうね。

以下の点には、注意が必要かもしれません。

  • 既存のDaemonプロセスが、なにか別の処理をしている場合は新たなDaemonプロセスを起動する
  • JavaVMの環境ごとに、起動するDaemonプロセスは分かれる(*1)
  • JavaVMの引数(ヒープの設定やファイルのエンコーディングなどのシステムプロパティなど)を変更しても、それ毎にDaemonが起動する(*2)
  • Daemonプロセスは、3時間のアイドル状態が続くと有効期限切れとなる

*1 使用するJavaを変えると、それ毎に起動するよってことなんでしょう
*2 GradleプロジェクトでJavaVMの設定を変えたりすると、やっぱりそれ毎に起動するよってことなんでしょう

Gradle Daemonのログ出力先

なんか、$HOME/.gradle/daemon配下にできます。

$ ll ~/.gradle/daemon/1.1/
合計 296
drwxrwxr-x 2 xxxxx xxxxx  4096 Aug  6 16:38 ./
drwxrwxr-x 3 xxxxx xxxxx  4096 Aug  5 22:34 ../
-rw-rw-r-- 1 xxxxx xxxxx 87515 Aug  5 22:35 daemon-19562.out.log
-rw-rw-r-- 1 xxxxx xxxxx 41735 Aug  6 15:47 daemon-21956.out.log
-rw-rw-r-- 1 xxxxx xxxxx 64493 Aug  6 15:50 daemon-22109.out.log
-rw-rw-r-- 1 xxxxx xxxxx 30329 Aug  6 16:34 daemon-22854.out.log
-rw-rw-r-- 1 xxxxx xxxxx 50267 Aug  6 16:40 daemon-23100.out.log
-rw-rw-r-- 1 xxxxx xxxxx  1596 Aug  6 16:40 registry.bin
-rw-rw-r-- 1 xxxxx xxxxx     2 Aug  6 16:40 registry.bin.lock

ファイル名は、「daemon-[Gradle DaemonプロセスのPID].out.log」のようですね。

Gradle Daemonの停止方法

gradleコマンドの引数に、「--stop」を付与します。

$ gradle --stop
Stopping daemon(s).
Gradle daemon stopped.

文字通り、停止します。

Gradle Daemonを使用しないようにする

gradleコマンドの引数に、「--no-daemon」を付与します。

$ gradle --no-daemon run

まあ、すでにDaemonプロセスがあっても使用しないので、遅くなるといえば遅くなります。

gradle.propertiesでDaemonを使用することを設定する

gradleコマンドで、「--daemon」を付与せずともDaemonを使用するようにすることを、gradle.propertiesというファイルを用意することで設定可能です。
http://www.gradle.org/docs/current/userguide/tutorial_this_and_that.html#sec:gradle_properties_and_system_properties

gradle.propertiesは

のいずれかに配置するそうです。

ここでは、プロジェクトディレクトリ直下に作成してみます。
gradle.properties

org.gradle.daemon=true

これだけで、そのプロジェクト内で使用するgradleコマンドはDaemonを使用するようになります。

ちなみに、配置先の2つ目である「Gradleのユーザホームディレクトリ」というのは

$HOME/.gradle

を指します。このディレクトリ直下に、gradle.propertiesを配置しておけばOKです。

あと、-Dシステムプロパティを使用することでも指定可能です。

$ gradle -Dorg.gradle.daemon=true run

こっちはあまり使わないでしょうけど…。