ABA Games

すごいぞ/ひどいぞ! 改め うーむ HotSpot


このページは、Sunから近いうちにリリースされるであろう HotSpotVM に対する期待をつらつらとつづったものです。 リリース後は、(すごいぞ/ひどいぞ)どちらかにフィックスされます。
5/1にfixしました。うーむ HotSpotになりました。

HotSpot目についたことヒストリ


人はなぜHotSpotを必要としたか

Javaは遅いです。はっきりいって。その堅牢でわかりやすい言語体系や、 マルチプラットフォームにかまけて大目に見られていたのも、今や過去の話。 「そろそろもうちょっとましなスピードで動いてもいいんじゃない?」とかいう 疑問がでてきてもおかしくありません。

そこでHotSpotです。詳しい技術的内容などは、上のページから たどると書いてありますが、要はより速い動作速度を実現してくれる 新しいJavaVMです。特に大事なのは、Javaを致命的に遅くしている Garbage Collectorが改善されることです。

非同期GCの弊害

リアルタイムゲームを作る人間にとって、Javaの非同期GCは 致命的な結果をもたらします。GCが働かないよう、プログラミングテクニックで 回避できないこともないのですが、自分が作ったものならともかく、 他の人が作ったライブラリを使った場合にGCが発生するのは避けられません。 たとえば、Java 3Dなどです。


ちょっとその前に Java 3D 1.1.1について (5/1追加)

Java 3D 1.1.1はマイナーバージョンアップではないぞ

HotSpotリリースに伴って、再びベンチをとろうとしたら、思いもかけない事態になってしまいました。

「速くなっとる」

そうです、1.1.1は1.1より高速化 & メモリ消費量の削減がはかられていたのです。

1.1.1におけるbefore & after

とりあえず、下のグラフをご覧ください。

before(1.1)


after(1.1.1)

メモリ使用量の青い線を見れば一目良然ですが、メモリ使用量が格段に減っています。 gcも発生していません。1.1.1はかなりのチューンがなされていることが分かります。

はて困った

困りました。いや、速くなったことはいいのですが、このページの本来の目的である、 HotSpotにおけるGCの効率化を見る、ということには、このサンプルは使えなくなってしまいました。

しょうがないので、「無理矢理GCを発生させるという暴挙」に出ます。以下のサンプルは、 一個のCubeを一回描画するために、Transform3Dを毎回生成します。本来こんなことはやっては いけないのですが、実験のためです。

注意してください。以下の結果はJava 3Dの本来の性能を引き出していません。
Java 3Dのサンプルを用いて、GCがどのくらいの悪影響を与えるかを みてみましょう。ここでは、立方体が多数飛び回るサンプルを作ってみました。
メモリ使用量と、1フレームを処理するのにかかった時間をグラフ化すると、 以下のようになります。青い線がメモリ使用量、赤い線が時間です。 (VMのメモリ使用量は、HotSpotVMでのデフォルトの最小4M、最大64Mです。 classicVMのデフォルト、最小1Mという設定では、HotSpotVMは起動すらしません)
GCの弊害が一目で分かります。メモリ使用量ががくっと落ちているところで GCが発生しています。その時点だけ、異常に処理時間がかかっています。 これのおかげで、Javaのプログラムは、かくっかくっという具合に動作 してしまいます。これはリアルタイムゲームにとっては致命的です。

そこでHotSpot

GCがどれだけひどい影響を与えるかがわかりました。 このままだとJavaでリアルタイムゲームを構築するのは不可能に近いでしょう。 そこで、HotSpotVMの登場です。 HotSpotVMで同じプログラムを動作させてみましょう。

ここで分岐します。どちらのシナリオになるかはリリース後に決まります。 (動きませんでした、という場合はそれが第3のシナリオです。)
5/1現在、HotSpotがリリースされたので、fixします。えーと、でも、 あんまり予想があってないです。一応分岐は右ということで
すばらしい! HotSpotVMの効能は明らかです。GCの発生する回数は 押さえられ、GCによるオーバヘッドも最小に押さえられています。 全体の動作速度も向上し、リアルタイムゲーム実現に向けて問題ない パフォーマンスを発揮しています。

これでJavaによるリアルタイムゲーム作成の道が開けました。 Java言語による開発効率を活かして、次々と優れたソフトウェアが 作られることでしょう。ありがとう Sun!
えーと、なんとも興味深い結果が得られてしまいました。序盤はとにかくめためたに遅いです。 しばらくすると、そこそこ、というかclassicVMと同等程度の速度で動作します。

後半の定常状態になると、GCでの処理速度低下もほとんど見られなくなり、非常にスムースに 動作を行います。ただし、全体の速度はとくに向上していません。

思うに、序盤の遅い部分で、いわゆるHotSpot(プログラム中で頻繁に使われている場所) を探し出しているのでしょう。HotSpotを見つけた後は、HotSpotを中心に最適化を行い、 動作しているのだと思います。でも、それほど改善されてません。

参考までに

ついでにとったデータがあるので一応書いときます。

インクリメンタルGC

-Xincgcオプションを指定することで、インクリメンタルGCを使うことができます。 インクリメンタルGCを利用すると、GCによる処理速度低下が発生しないかわりに、 全体の速度が低下するそうです。
なんか差が分かりません。全般的にメモリ使用量は減っています。

GC発生が無いアプリの場合

Transform3Dを毎回生成しない、本気モードのものをHotSpotにかけてみました。
大差ありません。こころもちメモリ消費量が少ないです。

結論

HotSpotは、発展途上の技術なので、まだ結論は出せません。 ですが、現時点のバージョンは、「まだ使わなくていーや」といった感じです。

ただしこれは、スタンドアロンのゲームアプリという、HotSpotがねらっているサーバの最適化という ところとはぜんぜん関係ないものを書いている人間の印象です。それでも、GCによる速度の低下が 押さえられていることは分かります。このことがうれしい人はたくさんいるはずです。

とりあえずは、今後に期待。余裕があれば、GL4Javaとの組みあわせでも実験してみます。
Rerurn もどる