メモリー管理に失敗したJavaアプリの実例
![](https://thinkit.co.jp/sites/default/files/styles/main_image_730x/public/main_images/1829_main_7.png?itok=YlqtMkQg)
HTTPセッションに起因するメモリー・リークを予防する
HTTPセッションは、画面に関する情報を格納できるため、複数の画面を遷移するアプリケーションを作る上で、非常に便利です。クライアント画面やリソースを表示する際に、再度同じ情報を取得させる必要がありません。また、Webアプリケーション全体でセッションの有効期間を設定することができます。一定時間アクセスされないセッションは、アプリケーション・サーバーによって破棄されます。
セッションに関しては、クライアントの状態を簡単に保管でき、不要になれば自動的に破棄される仕組みができています。しかし、アプリケーションの利用度合いによっては、セッションに格納されるオブジェクトのサイズは、可能な限り減らした方がよいでしょう。セッションは、サーバーのヒープ・メモリーを消費するからです。
実際に、業務アプリケーションの利用頻度というのは、機能ごとや日にちごとには平たん化しません。普段使わない機能や、定常的に頻ぱんに使う機能など、ばらつきが非常に大きいものです。特に、月次処理や月末処理で使うアプリケーションは、平常時と繁忙期での利用のされ方が大きく異なります。
同時利用ユーザー数が多くなれば、それだけセッションで使われるメモリーが必要になります。このため、単純にセッションを持ち続けるような設計をしてしまうと、メモリー不足となります。このケースは、エラーの再現性が非常に難しく、長期的に監視しなければ原因を特定できません。
|
図3: セッションを利用する際の問題点 |
とは言え、セッションの保持時間を短くすればよいというものではありません。あまりに短いと、セッションが切れやすく、再度ログイン処理から行う必要が生じるなど、利便性が大きく低下します。
このように、想定される利用頻度に合わせてセッションの保持時間を調整できます。どの情報をセッションに持たせるのか、保存したセッション内の情報を破棄するタイミングや画面遷移はどこかなどを細かく設計することで、アプリケーションをサイジングする際の切り口となります、また、セッションに起因する疑似的なメモリー・リークの発生を抑えることにもなります。
例えば、ログイン・ユーザーの情報は、どの画面でも再度利用されます。このため、ログイン・ユーザーの情報は、ログイン完了後に1度だけ取得しておけばよいことになります。これにより、無駄なI/Oが発生しなくなります。よほど大量の情報を格納するのでもない限り、問題ないでしょう。
セッションの情報を保存しない方がよい例もあります。データベースの検索結果をほかの画面でも使い回す設計をした場合や、アップロードを含んだユーザーの入力情報を一時的に保管しておく設計など、大きなオブジェクトになりうるデータをセッションに確保する場合です。メモリーが潤沢にある環境ではない場合、不要になった際には直ちに破棄するか、ファイルやデータベースに対して一時的に出力したものを再利用する方法で対応した方がよいでしょう。
HTTPレスポンス・サイズの肥大化による遅延
業務アプリケーションによっては、一括で数百件~数万件またはそれ以上の検索を行ってから、必要な情報をコピーし、Excelなど別ファイルに貼りつける、といった使い方をしているものもあります。これをWebアプリケーションに置き換えてブラウザ上でも一覧表示したい、といった要望が出ることがあります。
さすがに、このままの内容で設計、実装することはないと思いますが、ブラウザの画面に出力する件数とクライアントPCの性能によっては、システムが遅延しているように見えてしまうことがあります。検索処理そのものは3秒程度で終了し、アプリケーションがレスポンスを返す時間もあまりかかっていないのに、ブラウザの表示が終わるまで数秒~数十秒待つことがあるのです。
この遅延の原因は、2つです。(1)レスポンスするHTMLを生成するJSPやテンプレート・エンジンが、テーブルを表示するために大量のタグを出力する個所、(2)それを受け取ってレンダリングするブラウザによる影響、です。実際にレスポンスされたHTMLの量が数Mバイトにもなると、クライアントPCによっては遅延してしまうでしょう。
検索や照会画面では、絞り込み条件を指定して、さらに1ページでの表示件数を絞るのが当然ですが、ユーザーが一括出力を望むケースも稀ではありません。しかし、一括して大量にHTMLを出力するのは、ユーザーの使い勝手の面から見ても、アプリケーションの面から見ても、非常に厳しい内容です。この場合は、画面を出さずにダウンロード処理やバッチ処理などで対応し、システムにもユーザーにも負担を軽くする方針を検討するのが無難でしょう。
ほかにもいろいろ問題が出てきますが、今回はここまでとします。次回は、現在注目を浴びているNoSQLとインメモリー・データベースの概要を説明します。