コードジンのヘッダーが入ります
今日では、APサーバやJavaの開発生産性向上によって、Webシステムの構築が従来に比べてはるかに容易かつ短期間に行えるようになっている。「その反面、実際に本番稼働した後で、業務のピーク時などに性能上のトラブルが発生するといったケースが後を絶ちません」と日立製作所の中島恵氏は指摘する。そして、そのようなシステムの性能劣化を引き起こすものとしては、3つの要因が挙げられるという。すなわち、「CPUネック」「メモリネック」「バックエンドシステムによるネック」だ。
「特に昨今では、Webシステムで参照・更新されるデータのサイズがますます大きくなるなかで、Java VMのメモリ管理機能であるガベージコレクション(GC)に起因するメモリネックの問題が大きくクローズアップされています」と中島氏は説明する。具体的には、システムのメモリ領域の大容量化に伴って、GCによる停止時間が長時間化し、それがシステムの性能に甚大な影響を及ぼすに至っているわけだ。
周知の通りGCとは、Java VMが行う不要メモリの解放処理のことで、本来、プログラムで明示的に記述しなければならないメモリ解放処理を、システムで自動的に実施することにより、メモリ解放に伴う人為的なミスを防止し、システムの信頼性、安全性を保つための仕組みだ。GCには2種類あり、New領域を対象に随時、使用済みのインスタンスの削除を行う「Copy GC」と、Old領域の空きが無くなったタイミングですべてのメモリ領域を対象にインスタンスの削除を行う「Full GC」がある。
これら2つのGCの実行時間を比較してみると、例えばAPサーバで500MB?1GBのJavaヒープを利用しているようなケースでは、Copy GCが0.01?0.7秒程度であるのに対し、Full GCでは1?数十秒の時間を要することになる。GCが行われている間、アプリケーションの実行が停止状態となってしまうことを考えれば、特にFull GCがWebシステム上で行っている業務に与える影響はきわめて大きいといわねばならない。
こうしたJava VMのGCによる性能劣化の問題に対処する方策として、GCを併行で実行する「パラレルGC」や、業務処理とGCを同時に実行する「コンカレントGC」などのように、そのアルゴリズムを変更するというアプローチも従来から提案されてきた。しかし、こうした方法では、アルゴリズムが複雑化し、ユーザーがGCを適切にコントロールできないといった問題もあり、Full GCの発生自体を回避することはできない。
「そもそも一瞬で不要になるトランザクション処理に関わるテンポラリーの領域と、セッション情報などのアプリケーション実行中の長期にわたって保持され続けるような領域を、共にJavaヒープという1つのメモリ領域で管理するという方法自体に無理があると言わねばなりません。そこで、発想の転換による“次の一手”というべき手法が求められているわけです」と中島氏は強調する。
これに対し、「Cosminexus」のAPサーバでは、Java VMにおけるメモリ管理のあり方自体を見直し、新たなヒープ管理方式を採用することで、そうしたFull GCに関する問題に対しての有効な解決策を提案している。それが「明示管理ヒープ方式」(Eヒープ(Explicit Heap)方式)と呼ばれるものである。その特長は、Java VMのヒープ領域に関する用途の違いに着目し、対策を講じていることだ。
Java VMでは、New領域にはトランザクション処理などに関わる短命なインスタンスを格納するのに対して、Old領域にはセッション情報などの長命なインスタンスを格納。このとき、Old領域に確保されたセッション情報は、ログアウト後も残存し、ユーザーがログイン、ログアウトを繰り返すなかでそうした残存情報がどんどん蓄積していくことになる。その結果、Old領域に空きがなくなり、Full GCが発生することとなるわけである。
「これに対しEヒープ方式では、GC対象外の領域にEヒープと呼ばれる独自の領域を新たに設けて、セッション管理に代表されるような長命のオブジェクトをこの領域に割り当てることで、当該オブジェクトの利用するヒープ領域をGCの対象外にする仕組みを採用。Full GC処理に頼ることなく領域の開放を明示的に行うということを実現しています」と中島氏はその基本的なメカニズムを紹介する。つまり、こうした方式によって、Old領域に残存情報が蓄積していくことがなくなり、Full GCの発生自体を抑止できることになるわけだ。
Eヒープ方式が優れているのは、既存アプリケーション側の変更を一切行うことなく、適用が可能となっている点である。その仕組みは、次のような処理の流れによって実現している。
まず、業務アプリがセッションの生成を要求すると、Cosminexusではセッションの割り当てを行うとともに、Eヒープ領域の確保を行う。そして、業務アプリがNew領域に生成したオブジェクトをセッションオブジェクトとして設定すると、CosminexusがEヒープの関連付けを行った後に、Copy GCでNew領域から、Old領域ではなく、Eヒープ領域へと移動させることになる。「このようにセッションオブジェクトの登録、関連付け、移動を繰り返すことで、アプリケーションを変更することなく、セッションオブジェクトがEヒープに割り当てられていくことになります。セッションオブジェクトはNew領域で関連付け情報を付加されるため、アプリケーション側でヒープ管理方式を気にする必要がありません」と中島氏は解説する。
そして、業務アプリがセッションの終了を行うと、当該のEヒープ領域が削除されることになるが、このとき仮に削除対象のEヒープ内に共通情報など使用中のデータが存在する場合には、単純削除では領域外参照といったトラブルの発生も懸念される。これに対しCosminexusでは、Eヒープ領域の削除に際して、そこに参照されるべきデータが存在するか否かを解析し、そうしたデータがあればJavaヒープへの移動を行ったのち、削除処理を行うという仕組みをとっている。これにより、システムの堅牢性も確実に担保されることになる。
ここで、従来方式と比べたオーバヘッド増加による性能への影響が懸念されるが、Eヒープ方式では、従来と比べてCopyGC実行によるオーバヘッド増加にのみ限定されるため、処理性能への影響も1%未満と微小になっている。
以上のようなEヒープ方式の採用により、Cosminexusでは「Full GCレス」機能を実現。いわゆる“Stop the World”による業務停止の問題を解消しているわけだが、本来、このようなJavaオブジェクトに対するヒープ領域の割り当てや管理は、Java VMに一任されているため、外部から細かな制御を行うことはできない。
その点に関しては、Cosminexusでは従来からオリジナルのJava VMを提供してきたという経緯がある。「Java VMおよびAPサーバ、双方のレイヤを自前で提供しているからこそ、両者の密連携によるこうした仕組みの実現が可能なのです」と、中島氏は日立ならではの強みをあらためて強調し、セッションを締めくくった。