
事例に学ぶWebシステム開発のワンポイント(9)
メモリは足りているのに“OutOfMemory”
(株)NTTデータ
基盤システム事業部
重畠洋二
2003/2/15
|
本連載では、現場でのエンジニアの経験から得られた、アプリケーション・サーバをベースとしたWebシステム開発における注意点やヒントについて解説する。巷のドキュメントではなかなか得られない貴重なノウハウが散りばめられている。読者の問題解決や今後システムを開発する際の参考として大いに活用していただきたい。(編集局) |
| 今回のワンポイント Javaアプリケーションを動作させていて、「OutOfMemoryが出た」「Java VMが落ちた」という問い合わせを受けることがある。この場合、たいていはアプリケーションの問題や、設定の問題であることが多い。本稿では、HP-UX上でのJava VMを例に、OutOfMemoryが出る原因とその対処方法を紹介する。なお、本稿に登場する用語は第6回「APサーバからの応答がなくなった−GCをチューニングしよう−」で解説しているので、参照してから読んでほしい。 |
| Old領域が足りない |
|
今回の内容
|
| |
WebLogic Serverなどのアプリケーションサーバを動作させる場合はメモリがかなり必要になってくるので、New領域やOld領域を必要なだけ大きく取る必要がある。しかし、いくらOld領域を多く取ってもOutOfMemoryが発生するという問い合わせを受けることもある。
ガベージ・コレクション(以下GC)を行う時点においてルートセットからたどれるオブジェクトが多過ぎるため、フルGCを行ってもOld領域に全部入りきらない場合にOutOfMemoryが発生する。不要になったオブジェクトへの参照を外し忘れてしまうことにより発生することが多い。いわゆるメモリリークであったり、メモリリークに見えるような状態であったりする。
メモリリークについては、OptimizeitやJProbeのようなメモリデバッガを使用して、解放されていないオブジェクトを発見し、解放するように修正する必要がある。例えば、サーブレットコンテキストに格納したデータはセッションタイムアウト後も削除されないデータなので、削除し忘れに注意する必要がある。
メモリリークに見えるような状態は、例えば、セッションタイムアウトが非常に長い場合である。ユーザーとのインタラクションとしては終了していても、セッションの無効化(invalidate)を行わないと、セッションタイムアウトまでセッションにデータが残ったままとなる。セッションタイムアウトになれば解放されるが、セッションタイムアウトが非常に長い場合は、すでに使用しないにもかかわらずGCでも解放されないオブジェクトとなるので注意が必要である。
HP-UXでは-Xverbosegcオプションによって詳細にメモリ使用状況を把握することができるので、常にメモリの使用状況をチェックしておく必要がある。
| Java VMのPermanent領域が足りない |
クラスやメソッドの情報などが入るPermanent領域が不足した場合にOutOfMemoryが発生する。WebLogic Serverなどのアプリケーションサーバを動作させている場合は、Permanent領域を大きくする必要がある(-XX:PermSize=<初期値> -XX:MaxPermSize=<最大値>)。HP-UXのJava VMでは-XverbosegcオプションでPermanent領域をチェックする必要がある。
| .カーネルパラメータ(maxdsiz)が小さすぎる |
Java VMやアプリケーションサーバがnative method経由でメモリを確保(mallocなど)することがある。そこで確保したメモリの大きさがmaxdsizを超えた場合にOutOfMemoryが発生する。WebLogic Serverを動作させている場合は300Mbytes程度になることもある。samなどを使って、maxdsizを大きくする必要がある。かなり大きなサイズを指定してもこの状況に陥る場合は、native method内でのメモリリークも考えられる。
Glans Plusなどで該当のJava VMのメモリ使用状況を確認する。プロセスのデータ領域のVSSがmaxdsizを超えないようにする必要がある。
| カーネルパラメータ(maxfiles、maxfiles_lim、nfile)が足りない |
アプリケーションサーバなどでは、ソケットなども含めオープンするファイル数が多くなりやすい。そのため、ファイルに関するカーネルパラメータを調整する必要がある。samなどを使って、maxfiles、maxfiles_lim、nfilesの値を大きくする必要がある。
運用中のアプリケーションサーバについても、Glance Plusなどを使うことによって、現在オープンしているファイル数を取得することができるので、定期的にチェックしておく必要がある。
| ほかのプロセスが起動できない |
HP-UXのJava VMはEXEC_MAGIC形式を採用しているため、通常のSHARE_MAGIC形式のプログラムと比較して、プロセス固有のアドレス空間が広くなっている。また、UNIXにおいてほかのプロセスの起動はfork->execという手順を踏むために、execが行われる前のforkが同時に複数発生した場合、OSが必要とするメモリ量が現在確保しているメモリ量(物理メモリ+スワップ領域)を超えてしまう場合にOutOfMemoryが発生する。
アプリケーションサーバの場合はJSPの動的コンパイルなどに注意する必要がある。アプリケーションサーバには大量のメモリを割り当てていることが多いため、複数ページの動的コンパイルが同時に発生すると、アプリケーションサーバ自体のforkが発生し、一時的に大量のメモリを必要とすることになる。もちろん、JSPの動的コンパイルというのは一例なので、特にアプリケーションサーバなどでは、ほかのプロセスを起動させないように設定するということが必要である。
とはいっても、Javaではforkのみということはないし、たいていの場合はexec後のプロセスが必要としているメモリ量は小さい。ざっくりとした目安としてはforkが同時に2つ動作することぐらいまで想定していれば十分かと思われる。Javaのプロセスをforkするときに必要となるメモリ量も、該当プロセス全体のVSSとしておけば問題ないであろう。
なお、HP-UXの仮想アドレス空間などについては『HP-UX TUNING AND PERFORMANCE:Concepts,Tools and Methods』(ISBN 0-13-102716-6)が参考になる。
| EXEC_MAGICで使えるPrivate領域を使い果たした |
EXEC_MAGIC形式のプログラムは、プロセス固有の領域として2Gbytesまで使用することができる。プロセス固有の領域には、テキスト領域、データ領域、(プロセス固有の)メモリマップファイルなどが割り当てられる。Java VMのNew領域、Old領域、Permanent領域は(プロセス固有の)メモリマップファイル上に取られるということもあり、Large Heap機能を使用しないJava VMでは、約1.7Gbytesまでしかメモリを割り当てることができない。しかし、しかし、「カーネルパラメータ(maxdsiz)が小さすぎる」の節でも述べたとおり、アプリケーションサーバではデータ領域にもかなりのメモリが必要とされる。これらが原因で、プロセス固有の領域の2Gbytesを使い切ることがあり、そのときにもOutOfMemoryが発生する。特に、Java VMの起動オプションで1.5Gbytes程度のメモリを割り当てているところは注意が必要となる。
さて、最近のJava VMにはLarge Heapオプションが追加された。Large Heapとは、上で述べた1.7Gbytesよりも多くのメモリをJava VMに割り当てる設定である。簡単にいうと、EXEC_MAGIC形式でプロセス共有の領域として管理されているアドレス空間もプロセス固有の領域として使うことで、上限を引き上げるというものである。
| HP-UX 11とHP-UX 11iでは対応が異なる |
| HP-UX 11iではJDK 1.3.1_01以降でLarge Heapオプションが使用できる。HP-UX 11ではJDK 1.3.1_06以降から使用することができる。使用できるメモリ量の詳細については、http://www.hp.com/products1/unix/java/java2/sdkrte1_3/infolibrary/sdk_rnotes_1-3-1-06.html#heapを参照してほしい。 |
ただし、根本的な対策としては、必要なメモリ量が少なくなるようにすることである。確かにLarge Heapを使用することでいくらか領域を拡大することはできる。しかし、領域を拡大するとGCの時間が長くなったり、「ほかのプロセスが起動できない」の節に示したようなforkを行う際に必要なメモリ量が増えたりなどと弊害が出てくることとなる。Large Heapオプションは取り急ぎの対応策とし、その間にアプリケーションを見直して使用メモリ量の削減を検討すべきだと思われる。
| INDEX | |
| 事例に学ぶWebシステム開発のワンポイント | |
| 第1回 クラスタ化すると遅くなる?(2002/3/9) | |
| 第2回 キャッシュが性能劣化をもたらす“なぞ”を解く(2002/3/23) | |
| 第3回 クラスタは何台までOK?(2002/4/19) | |
| 第4回 マルチスレッドのいたずらに注意(2002/5/14) | |
| 第5回 サービス中にアプリケーションを入れ替える(2002/6/4) | |
| 第6回 APサーバからの応答がなくなった、なぜ?(2002/11/30) | |
| 第7回 低負荷なのにCPU使用率が100%?(2002/12/11) | |
| 第8回 文字化け“???”の法則とその防止策(2003/1/28) | |
| 第9回 メモリは足りているのに“OutOfMemory”(2003/2/15) | |
| 第10回 レスポンスキャッシュでパフォーマンス向上(2003/3/29) | |
| 第11回 JDBC接続を高速化する(2003/4/18) | |
| 第12回 ブラウザキャッシュでパフォーマンス向上(2003/5/10) | |
| 第13回 ファイルアップロード/ダウンロードに潜むわな(2003/6/12) | |
| 筆者プロフィール |
| 重畠 洋二(しげはた ようじ) 現在、株式会社NTTデータビジネス開発事業本部に所属。 技術支援グループとして、J2EEをベースにしたWebシステム開発プロジェクトを対象に、技術サポートを行っている。特に、性能・信頼性といった方式技術を中心に活動中。 |
| Java Solution全記事一覧 |
ホワイトペーパー(TechTargetジャパン)
- Webの表示速度を遅くする「SSLハンドシェイク」とは (2010/2/9)
安全性を担保しようとWebページにSSLを適用すると、負荷の高い処理が実行される。速度と安全性は両立できるのか? - クラウド活用「雲活」のために押さえるべき39のポイント (2010/2/2)
活用するべきサービスか否か、クラウドの利点・問題点、クラウドプラットフォーム提供企業になるための条件、開発者がするべきことに分けて紹介 - 再利用性の高いクラス作成に重要な“アクセス制御” (2010/1/28)
Javaのアクセス修飾子public、private、protectedや、Eclipseで簡単に作れるアクセサメソッドgetter、setterについて解説 - DB設計の神ツール「ERMaster」なら、ここまでできる (2010/1/21)
直感的なUIに、カスタマイズ可能な、Excel出力のテーブル定義書、辞書機能など多機能なERモデリングの無料Eclipseプラグインです
|
|
スキルアップ/キャリアアップ(JOB@IT)
スポンサーからのお知らせ
- - PR -
- - PR -
お勧め求人情報

**先週の人気講座ランキング**
〜CCNA編〜
| ◆ | 企業の仮想化に足りない“発想”とは? 仮想化運用管理のキモは意外なところに! New! |
| ◆ | 操作もマニュアルも分かりやすい! ユーザー視点で開発されたPC管理ツール New! |
| ◆ | 仮想化すればコストは削減できるか? 仮想化に必要な「3つの視点」を解説する |

| ◆ | セキュリティを知り尽くす上野氏が登壇! @ITメールソリューションLive! in Tokyo |
| ◆ | 運用管理の課題を“2つの観点”から分析 ユーザー満足度の高い「仮想環境」とは? |
| ◆ | 世界に通用するストレージの作り方とは? 製品に込めた思いを富士通の開発者に聞く |

| ◆ | OSSで手間も時間も、障害も減った―― 「マピオンの事例」オープンソース活用法 |
| ◆ | 「ノートPCの持ち出し禁止」で大丈夫? 情報漏えいを防ぐ管理手法とインフラは? |
| ◆ | 1日の処理を1秒に――MySQLの達人が語る 「コスト削減」できるチューニング |

| ◆ | ドキュメント作成を自動化して、SEの作業 効率を大幅アップ! Visio 2007の魅力 |
| ◆ | 急速に広がるHyper-Vでのサーバ仮想化 そのベストプラクティスをデルが解説 |
| ◆ | @IT主催セミナーで語られた、「担当者に 求められるセキュリティ対策」をレポート |

| ◆ | @IT「Windows 7」 特設サイトオープン! 最新情報・移行ノウハウを公開しています |






