javaのバックグラウンドを長く持つ自分にとって最近のお気に入りの言語はgroovyです。
もともと自分は言語の習得にコストを掛けたくなく、新しい言語が少なからず生み出される現状に少なからず嫌悪感を持っているところがなくはないです。
歴史的な経緯で高級言語が生み出されるようなことは好ましいのですが、同時代に構文だけが異なる似たような言語や、今ままでの低級言語のAPIから何故かひどく乖離した構文を提供する言語は疎ましくも思います。
もともとjavaは広く普及していたので自然と使わざるを得なかったのですが、広く使われているだけあってかなり洗礼されています。
javaはやはりLLと比較した時に型付き言語であるためコンパイル時点でかなり品質を担保できます。
またそれでいてCやC++などのレガシーな言語ほどコストを掛けずに開発できることから自分の中では攻撃力/防御力ともに優れた言語、と言った印象でした。
もっというと優れたIDEがあるのがよいですね。
なんですが欲を言うとjavaはその防御力の高さや歴史的には比較的古くから生み出された故にそのAPIに一部不満がある点もなくはないのです。
java8などの新しいAPIでは新しい流れをかなり汲み取っているようで不満があるかというとそういうわけでもないですが、いかんせん他の流れが早すぎるのだと思います。
新しい言語と比べると記述がかったるいことがあります。
このgroovyという言語はjavaというバックエンドを全く損なうことなく、実装速度をぐっとお仕上げてくれるようなものです。
というわけですごく気に入っているのです。
が、良いことばかりかなというと深い部分に行ったりするとちょっと不明な挙動を示したりすることもあるんですが、今回取り上げるのは gradle daemon と呼ばれる仕組みです。
groovyは様々なビルドシステムを利用することができますが、その中でも有名なものの一つにgradleと呼ばれるものがあります。
gradleはgroovyで開発されており、javaやgroovyのビルドツールとして利用できます。
ビルとツールによりgroovyソースはコンパイルされjavaのclassファイルへと変換されたりと様々な事が行われるのですが、その際に多くのオーバーヘッドを含みます。
そのためgradleではそのビルドコストを少なくするためにgradle daemonという仕組みを提供しています。
このdaemonは常駐することでビルドにかかるコストを削減してくれます。
今回この gradle daemon によりちょっとした不都合が起こりました。
現在個人として開発中のシステムで、ものすごくメモリを食うプロセス(javaではない)を起動しなければなく、しかしメモリを食いすぎるゆえに oom-killer によってプロセスが殺されることが続きました。
はじめはそのプロセスのメモリの消費量を抑えることを考えていたので、それが非常に困難であることがわかり、発想を変えて他のプロセスの精査を行うことにしました。
で、TOPコマンドで見てみるといるじゃないですか。でかいのが。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 15032 z 20 0 3495m 433m 14m S 130.3 23.1 1:09.40 java
上記のプロセスの実態は gradle daemon です。
メモリを大量に消費していますね。物理メモリのおよそ25%をgradle daemonが抱えていることになります。
上記はコンパイル時の状態なんですが、daemonはその目的達成のために各種リソースを抱えたまま常駐します。
これはとんでもないということで即見直しの対象として検討しました。
使用されなければswapに吐き出されるんですが、swapに吐き出されるとしてもswapを消費してしまって結構邪魔だし、そこまで頻繁にビルドしない。
そして結局 gradle daemon も oom-killer に殺されているという始末。
というわけでdaemonを起動しないようにしました。
実装としては gradle.properties に下記のように記述を加えました。
org.gradle.daemon=false
これにより無事にメモリを確保することができ、目的のプロセスを起動することができました。
gradleは便利さ故に色々できるのですが、マニュアルがかなり膨大です。
しかも失礼ですが和訳は結構わかりにくいです。おそらく、原文を読んだほうが良いでしょう。
便利なものですが気をつけて使わないとトラブルの温床となりますね。
コメントを残す