= CSSのDataBrowserのパフォーマンスチューニング = CSSのDataBrowserで長期間のグラフあるいは多数のグラフを描かせようとしたときに グラフを描き終わるまで非常に長時間掛かったりエラーになったりしてしまうことが良く起こる。 これはグラフを描くためのデータを格納するメモリが不足することが原因で起こるが、 メモリに関するパラメータをチューニングすることでどのようにパフォーマンスが改善されるか ベンチマークテストにより確認する。 == はじめに == CSSではJavaが使用されている。 Javaで使用するメモリにはヒープ(Javaヒープ)と非ヒープがあり、 CSSのDataBrowserでグラフを描くためのデータはヒープに格納される。 CSSの設定ファイルcss.ini内の{{{-vmargs}}}行以降でJavaで使用するメモリに関するパラメータが設定されている。 {{{ -Xmx1024m -XX:MaxPermSize=128M }}} このうち非ヒープであるPermanent領域の最大サイズを指定しているパラメータ{{{-XX:MaxPermSize=128M}}} については今回は変更しない。 ベンチマークの条件 * 使用したPCは、64bit版Windows7 Pro、Core i5(4core)、実装メモリ8GB、利用可能メモリ7.9GB、ネットワーク100Mbps * 使用したCSSはkek版3.1.2 64bit。使用したJavaはJava SE 7 Update 55(1.7.0_55)。 * 使用するデータは1つ。(PFROP:BEAM:FAST_CURR 0.1秒毎の更新) * データの開始日時を固定。(2014/05/10 00:00:00) * 何日分のグラフを描くプロットファイルを多数用意しておく。(1日分、2日分、、、) * プロットファイルを開いた時からグラフを描き終わるまでの時間を測定する。 * 時間の測定にはストップウォッチを使い、1秒未満はすべて切り捨てる。 * 時間測定は最大10分とし10分を超えた場合は中断して、結果なしとする。 * 1つの測定毎にCSSを再起動する。 このような条件でメモリに関するパラメータを変化させてベンチマークを行った。 == ヒープサイズを増やす == Xmxパラメータはヒープの最大サイズを指定するパラメータである。[[BR]] あくまでも最大サイズを指定するものであり、実際のヒープサイズはデータ量により変わり、 データ量に応じてヒープサイズは最大サイズまで自動的に拡張される。 初期設定ではヒープの最大サイズが1GB(1024MB)に指定されている。 まずXmxパラメータでヒープの最大サイズを初期設定の1GB、4GB、6GB、8GBと増やした。(図1)[[BR]] ヒープサイズを増やせば処理可能な日数が増え、処理時間もデータ量(日数)に比例する(Xmx近似の点線)。[[BR]] ヒープサイズはデータの読み込みが進むにつれ次第に最大サイズ近くまで拡張されていった。 次にXmsパラメータをXmxと同じ値にして測定した。(図2)[[BR]] Xmsはヒープの初期サイズ指定で、Xmxと同じ値を指定すればヒープサイズは固定される。[[BR]] ただしヒープサイズを大きなサイズに固定したからといって実際にデータ量が増えなければ OSがメモリを割り当てることはないので、PCのメモリを無駄に占有するわけではない。 ヒープサイズを固定した場合にXmx近似より処理時間が短く完了する比例関係部分がある(Xms近似の点線)。[[BR]] データ量がヒープのOld領域の不足が起こらないで済む場合はXms近似で処理が完了するが、 !Old領域が不足してFull GCが起こり始めるとXmx近似になっていく。 ヒープサイズを固定しない場合はヒープサイズの拡張とともにFull GCが行われていると思われる。 [[Image(memorytuning_fig1.png, 40%)]] [[Image(memorytuning_fig2.png, 40%)]] 処理時間については、ヒープサイズを固定した場合のほうが処理時間が短縮されることが多く、 8GBの20日分の処理時間を比較すると215秒から156秒へと59秒短縮されている。(図3,4,5) 処理可能な日数については、ヒープサイズを固定した場合に改善したというよりも、 ヒープサイズが可変の場合、ヒープサイズを拡張する際にメモリの断片化が起き、 GCを行っても断片化が完全には解消できずにメモリの利用効率が悪化しているのではないだろうか。 [[Image(memorytuning_fig3.png, 40%)]] [[Image(memorytuning_fig4.png, 40%)]] [[Image(memorytuning_fig5.png, 40%)]] == ヒープのOld領域を大きくする == 次にNewRatioパラメータを変更してみる。[[BR]] NewRatioパラメータはヒープのNew領域の大きさに対するOld領域の大きさの比率を指定する。[[BR]] !NewRatio=2とした場合New1:Old2になり、New領域の大きさはヒープサイズの1/3、Old領域の大きさは2/3になる。 (似たパラメータとしてNew領域の大きさを指定する、!NewSize、MaxNewSizeというパラメータもある。) Java !HotSpot VMにはクライアントVMとサーバVMのチューニングの異なる2種類のVMがあり、 NewRatioパラメータの初期値はクライアントVMが8、サーバVMが2となっている。[[BR]] PCの構成によってどちらを使用するか決定される。自分のPCでどちらのVMが使用されるかは {{{java -version}}}コマンドの出力で確認できる。[[BR]] Windowsの場合、32bit JavaではクライアントVM、64bit JavaではサーバVMが使用される。 Xms4Gとしてヒープサイズを4GBに固定して、NewRatio指定なし、!NewRatio=2、8、10、12、14、16、20と変化させた。(図6)[[BR]] !NewRatio指定なしとNewRatio=2の結果は同じであることが確認できた(64bit Javaを使用)。[[BR]] NewRatioを増やすにつれてXms近似の範囲で処理完了する日数が増えていくが、 次第に改善幅が小さくなっていき、16と20では同じ結果になった。[[BR]] これは、NewRatioが16の場合はOld領域の大きさがヒープの94.1%(16/17)、20の場合は95.2%(20/21)と、 Old領域の大きさが1%(45MB)しか変わらないからだろう。 [[Image(memorytuning_fig6.png, 40%)]] Xms6G、Xms8Gの場合も似たような結果になった。(図7,8)[[BR]] NewRatioが16と20の場合の1%の違いは、6GBでは69MB、8GBでは91MBにすぎないが多少の改善が見られた。[[BR]] 4GBの場合でも1日分のデータ量の違いでは結果に差がなかったが、半日や1/4日分のデータ量の違いだとしたら 多少なりとも結果に差がでたことだろう。 [[Image(memorytuning_fig7.png, 40%)]] [[Image(memorytuning_fig8.png, 40%)]] 以上の結果から同じヒープサイズで、最大ヒープサイズを指定しただけの場合(Xmx)と、 ヒープサイズを固定かつOld領域を大きくした場合(Xms NR16)とを比較すると、 処理完了までの時間と日数(データ量)がかなり改善され、 Xmx8GとXms8G NR16の場合では同等の処理時間で10日分多いデータが表示できるようになった。(図9,10,11) さらに、少しズルい比較になるが、Xmx4GとXms8G NR16を比較すると 22日分多いデータが表示できるようになり、2.5倍に改善された。(図12)[[BR]] 処理時間についてはデータ量が多いためそれなりにかかるがXms近似から外れてはいない。 [[Image(memorytuning_fig9.png, 40%)]] [[Image(memorytuning_fig10.png, 40%)]] [[Image(memorytuning_fig11.png, 40%)]] [[Image(memorytuning_fig12.png, 40%)]] == まとめ == CSSのDataBrowserで長期間のグラフあるいは多数のグラフを描かせるためには CSSに多くのヒープ(メモリ)を割り当てる必要がある。[[BR]] データ量が増えるため必要なヒープも多くなるのは当然である。 しかし単にヒープの最大サイズを多くするだけでは不十分で、 ヒープサイズを固定しOld領域の割合を大きくし、 Full GCをなるべく起こさないようにチューニングすることで パフォーマンス(グラフの日数や数、処理完了時間)はかなり改善される。 また、PCの利用可能メモリの制限からCSSに割り当てられるヒープサイズが制限される場合でも、 Old領域の割合を大きくすることで同じヒープサイズでもパフォーマンスを改善することができる。