リクエストを処理する中で、遅くなっているものは何か?
よく考えられるもは、ロジックの無駄な処理(処理する必要のないものを処理している)。リソースの使い方。
で、まずはロジックの無駄という意味では、意味のない処理は見つからず。
で、遅くなっているところというのを考えると
リソースの確保の部分。
new byte [ XX ];
これは、ある程度のサイズになったとき、Heapの確保が発生するので、場合によって、数msかかる。これが1か所ならまぁいいのですが、中の処理では、Socketの読み込みバッファから、エンコード用のバッファ、出力用のバッファまで広く使っており、1回のリクエストで、少なくとも5回以上は生成しておりました。
これを何とかできないか?と考えたのが、BufferPoolというクラスを作ることでした。
これの役目は・・・
- byte配列の確保を毎回やらせないことで、GCのコストを抑える。Heapの確保と解放をあまり発生させない。
- 一定数事前に配列を生成し、領域を確保することで生成のコストを抑える。
- 必要なサイズに応じたものを返す。
- 足りなければ、作る。
- 足りなくて作ったものが、既定の確保しておく領域を上回る場合には、解放する。
これで得られる恩恵は、思ってた以上に大きく、リクエストあたり数ms減りました。
これに対して個人的な見解は・・・・
GCはリソースやメモリの再利用があるので、そこである程度同じことさせているときは、次第に早くなるのですが、HTTPリクエストやら、Socket通信などでは、同じリソースのサイズを要求しないことが多く、メモリの断片化が起きたり。GCが動くことで、CPUリソースを消費したりということではないかなぁと思ったりしたが、それを明確に確認できる方法は思いつかなかった。。。GCの呼び出し回数が減っているというくらいかな。
続く・・・