WebSphere Application Server でメモリー・リークを検出して分析する: パート 1: メモリー・リークの概要

この記事では、Java™ ヒープ・メモリー・リークに対処するために IBM® WebSphere® Application Server で使用可能な手法の概要を示します。

Indrajit Poddar, Advisory Software Engineer, IBM

Indrajit Poddar's photoIndrajit Poddar はソフトウェア・エンジニアリング顧問であり、現在は IBM Software Group, Strategy and Technology チームのメンバーです。製品 (WebSphere Application Server、Process Server、Portal Server、および Tivoli および Rational 製品) の IBM Software Group ポートフォリオでサービス指向アーキテクチャーを使用したコンポジット・アプリケーションの設計に関心を持っています。ペンシルベニア州立大学でコンピューター・サイエンスおよび工学の修士号を取得し、インドのインド工科大学カラグプル校でコンピューター・サイエンスおよび工学の学士号を取得しました。



Robbie John Minshall (rjminsha@us.ibm.com), WebSphere Performance Development, IBM

Robbie John Minshall は、現在 IBM Software Groups のサービス指向アーキテクチャー用の標準データ・オブジェクトの開発に取り組んでいます。もともとはニュージーランド出身で、ジョーンズ・ホプキンス大学を優秀な成績で卒業して、数学の学位およびコンピューター・サイエンスの学位を取得しました。Robbie の専門は、アプリケーションのベンチマークおよびスケーラビリティー、メモリー・リーク検出など、J2EE 環境でのパフォーマンス、正常性、およびシステム・モニターに関するオートノミック・エージェントです。



2006年 6月 28日

はじめに

メモリー・リークによる損失は深刻であり、多くの場合、実稼働環境のダウン・タイムまたはデプロイメント・スケジュールの遅延に直接つながります。あいにく、適切なテスト・ソリューションの費用も多大であり、お客様はたいてい必要なリソースに投資することを望んでいないか、または投資することができません。

メモリー・リークを解決するための最善の方法は、明らかに、テストで検出して解決することです。テスト・スケジュールがあって、典型的なワークロードと異常なワークロードを実行できる実稼働環境と同一のテスト環境が用意されていて、システム・テストを専門とする適切なスキルを持った技術者がいることが理想です。これは、できる限り無駄なく実稼働に移すことができるようにするための最善の方法です。ただし、この資料で焦点を当てるのは、そのような環境を設計して準備すること、および関連する文化的な変化ではありません。

Java でのメモリー使用量の問題には、次の 4 つの共通カテゴリーがあります。

  • Java ヒープ・メモリー・リーク
  • ヒープのフラグメント化
  • メモリー・リソースの不足
  • 固有のメモリー・リーク

WebSphere Application Server は、Java ヒープ・メモリー・リークに対処するのに役立つ 2 つの補完的なテクノロジーを導入しました (これらのツールは、メモリー・リソースの不足が引き起こす問題にもある程度対処します。この記事では、これらの 2 つ問題の類似点については扱いません)。

一般に、不要になったオブジェクトへの参照をアプリケーションが意図せず (プログラムのロジック・エラーが原因で) 維持した場合に、Java ヒープ・メモリー・リークが発生します。こういった意図しないオブジェクト参照があると、組み込みの Java ガーベッジ・コレクションのメカニズムは、これらのオブジェクトが使っていたメモリーを解放できなくなってしまいます。このようなメモリー・リークの一般的な原因は、次のとおりです。

  • 削除せずにコレクションに挿入
  • 無制限のキャッシュ
  • 呼び出されないリスナー・メソッド
  • 無限ループ
  • 多すぎるセッション・オブジェクト
  • 不適切に作成されたカスタム・データ構造

構成上の問題またはシステム容量の問題があると、メモリー・リソースの不足が原因でメモリー使用量の問題が起こることがあります。例えば、Java 仮想マシンで許容される最大ヒープ・サイズが、メモリーのユーザー・セッションの総数を収容するには低すぎる値に -Xmx パラメーターを使って構成されている可能性があります。あるいは、システムに、現在のワークロードに対応するのに十分な物理メモリーがないことが考えられます。固有のメモリー・リークは、非 Java コード (例えば、Type-II JDBC ドライバー) でのメモリー・リークであったり、Java プロセスのアドレス空間の非ヒープ・セグメントにおけるフラグメント化によるものです。

この記事は、IBM WebSphere Application Server にデプロイされたアプリケーションを扱う Java 開発者、システム管理者、および問題判別コンサルタントのために記述された入門記事です。

メモリー・リークの根本原因を突き止めるための既存の手法の問題

システム管理者にとって特に面倒なメモリー・リークを引き起こす問題は数多くあります。

  1. Java メモリー・リークの根本原因を突き止める従来の手法では、パフォーマンスの面で大きな負担がかかり、実稼働環境での使用には適していないことがあります。通常、このような手法には、ヒープ・ダンプ分析、JVMPI (Java Virtual Machine Profiler Interface) エージェント、または JVMTI (Java Virtual Machine Tools Interface) エージェントへの接続、あるいはコレクションへの挿入と削除を追跡するバイトコード挿入の使用などが含まれます。

  2. クラスタリングなどの従来の冗長な方法は、ある程度しか役に立ちません。メモリー・リークは、クラスター・メンバー全体に広がります。影響を受けるアプリケーション・サーバーの応答速度は、ワークロード管理の手法を低下させます。これによって、正常なサーバーに要求が送信され、調整されたアプリケーション・サーバーのクラッシュが発生する可能性があります。

標準的な分析ソリューションでは、実動サーバーに影響を与えずに問題を再現して分析を実行できる、隔離されたテスト環境にアプリケーションを移動する必要があります。このようなテスト環境で再現することは困難であるため、関連するメモリー・リークの損失は増大します。

これらの問題の原因は、従来の手法では検出と分析の両方を実行しようとすることにあります。

WebSphere のソリューション

WebSphere Application Server V6.0.2 以降は、問題の検出と分析が分かれた、2 つのステージからなるソリューションを提供します。

最初のステージは、実動の WebSphere Application Server ランタイム内で実行される単純なメモリー・リーク検出メカニズムです。この単純な検出手法は、費用がかからず、広く使われている Java ヒープ使用量の統計を使ってメモリー使用量の傾向をモニターし、メモリー・リークを早期に通知します。これによって、管理者は、適切なバックアップ・ソリューションを準備する時間を確保できます。また、テスト環境での再現に関して、費用がかかり、ストレスのたまる問題を発生させずに、オフラインで問題の根本原因を分析する時間を確保することができます。

ソリューションの 2 番目のステージは、実動アプリケーション・サーバーの外部でヒープ・ダンプを分析するオフライン・ツールである、MDD4J (Memory Dump Diagnostic for Java) です。これは、大規模なオフラインのメモリー・リーク分析ツールで、複数の既存のヒープ・ダンプ分析ツールを単一のユーザー・インターフェースに組み入れたものです。

検出と分析の間のギャップを埋めるために、IBM JDK で稼働している WebSphere Application Server 用の、自動化されたヒープ・ダンプ生成機能が提供されています。メモリー・リーク・パターンの検出時には、この機能は、MDD4J を使った比較分析を容易にするために、メモリー・リークに合わせた複数のヒープ・ダンプを生成します。さらに IBM JDK は、OutOfMemoryError が検出された場合に、自動的にヒープ・ダンプを生成するように構成されています。管理者は、短期間、低パフォーマンスになることを回避するために、ロード・バランスを設定するか、メモリー使用量が低い時にヒープ・ダンプを生成する必要があります。


メモリー・リークの検出

単純なメモリー・リーク検出は、空きメモリーの減少傾向をモニターすることで行います。

リークは非常に高速か極めて低速であるため、短い間隔と長い間隔の両方についてメモリー使用量の傾向が分析されます。さらに、ガーベッジ・コレクション・サイクル後のおおよそのメモリー使用量の減少傾向を分析することで、ガーベッジ・コレクション・サイクル後の平均的な空きメモリーが特定のしきい値を下回っているような状況を検出します。そのような状況は、メモリー・リークの兆候、またはリソースが少なすぎるアプリケーション・サーバーでアプリケーションを実行している兆候のいずれかです。この単純なメモリー・リーク検出機能は、すべてのプラットフォーム用の WebSphere Application Server バージョン 6.0 以降の全バージョンで使用可能です。

また、特に iSeries® プラットフォーム用に、iSeries の WebSphere Application Server には、DASD (Direct Access Storage Device) で Java ヒープ・サイズが拡張されるかどうかを検出するための追加機能があり、サイズが拡張されることや、次のいずれかが発生していることを管理者に通知するアラートを出します。

  • 有効なメモリー・プール・サイズが小さすぎる
  • リソースが少なすぎる
  • メモリー・リーク

バージョン 6.0.2 の zSeries® サポートには、単一のサーバント・トポロジーのみが含まれていますが、バージョン 6.1 では拡張されており、複数のサーバント・トポロジーが含まれています。V6.0.2 では、単一のサーバント・トポロジーによるメモリー・リーク検出の有効範囲は、問題判別にまたはテスト環境に制限されます。

図 1 は、メモリー・リーク検出機能によって生成された通知例を示しています。この通知は JMX を介して送信されて、管理コンソールに表示され、サーバー・ログに記録されます。

図 1. メモリー・リークの通知例
メモリー・リークの通知例

自動化されたヒープ・ダンプ生成機能 (IBM JDK でのみ使用可能) は、メモリー・リークが明らかになった後、OutOfMemoryError が原因でアプリケーション・サーバーがクラッシュする前に、ヒープ・ダンプを生成します。この機能は、メモリー・リークが増えると 2 番目のヒープ・ダンプを生成します。2 つのヒープ・ダンプが、MDD4J を使った比較分析を容易にします。

自動化されたヒープ・ダンプ生成は、デフォルトで有効にするか、MBean 操作を使って適切なときに開始することができます。

WebSphere Extended Deployment

単純なメモリー・リーク検出は、WebSphere Application Server および WebSphere Application Server Network Deployment で使用可能であり、すぐに操作できるように設計されていますが、完全に構成可能でもあり、拡張オートノミック・マネージャーまたはカスタムの JMX クライアントと相互作用するよう設計されています。WebSphere Extended Deployment は、そのような関係の例です。

WebSphere Extended Deployment には、メモリー・リーク検出を構成するポリシーがたくさんあります。あるポリシーは、(アプリケーションのパフォーマンスを維持するためにワークロード管理を使って) 分析用に複数のヒープ・ダンプを取得することによって、メモリー・リークの通知に対応します。別のポリシーは、不具合が発生する前にアプリケーション・サーバーを再始動するために、アプリケーション・サーバーのメモリー・レベルが深刻な場合を単にモニターします。


メモリー・リーク分析

メモリー・リークが検出され、ヒープ・ダンプが生成されると、分析のために実動サーバーの外部の問題判別マシンに転送されることがあります。

MDD4J は、メモリー・リークの根本原因の判別プロセスで役立つオフラインのヒープ・ダンプ分析ツールです。分析メカニズムは、リークが発生している疑いのあるデータ構造クラスおよびパッケージを特定します。この特定によって、システム管理者は、メモリー・リークの根本原因をいくつかのコンポーネント・アプリケーションに絞り込むことができます。

WebSphere Application Server は、サード・パーティーからの J2EE アプリケーションをホストするためのコンテナーを提供します。Java スタックは時間とともに進化するため、ますます多くの抽象化層およびコンポーネント化が基本 Java アプリケーションおよび WebSphere Application Server スタックに追加されるようになっています。これは、メモリー・リークが発生したときの問題判別に大きな問題をもたらします。数多くのサード・パーティー・アプリケーションをホストしている WebSphere Application Server は、メモリー・リークに直面しているシステム管理者にとってブラック・ボックスのようなものです。そのような状況での最初のステップは、メモリー・リークの根本原因を 1 つまたは少数のコンポーネントに絞り込むことです。根本原因は、多くの場合、1 つの障害のあるコンポーネント・アプリケーションにあります。システム管理者は、MDD4Jの分析結果を活用することで、IBM にサポートを依頼せずに、障害のあるコンポーネントをより迅速に特定できるようになりました。

障害のあるコンポーネントを特定した後、システム管理者は、開発者に働きかけます。開発者は、より小さな環境でこの問題を再現して、ロギングでデバッガーまたは特定のトレース・ステートメントを使って障害のあるソース・コード・メソッドを特定し、メモリー・リークを解決するためにアプリケーション・コードまたは構成のいずれかに必要な変更を行います。共通の構成上の問題を特定するためには、障害のあるコンポーネントまたはリークが発生しているオブジェクトを把握するだけで十分なことがあります。例えば、数多くの HTTP セッション・オブジェクトを検出すると、HTTP セッション・タイムアウト構成がわかります。

このツールは、2 つの主なタイプの分析機能を備えています。

  • 単一ダンプ分析は、OutOfMemoryExceptions 例外が発生すると IBM Developer Kit, Java Technology Edition によって自動的に起動されるメモリー・ダンプで、最も一般的に使われています。この種の分析は、ヒューリスティック・プロセスを使用して、子オブジェクトを数多く持つコンテナー・オブジェクトが入った疑いのあるデータ構造を特定します。このヒューリスティックは、収容されているオブジェクトを保管するために内部で配列を使用する Java コレクション・オブジェクトでリークが発生しているのを検出する場合に極めて効果的です。また、このヒューリスティックは、IBM サポートで処理された数多くのメモリー・リークの事例で有効であることがわかっています。

  • 比較分析は、メモリー・リークが発生しているアプリケーションを 1 回実行する間 (すなわち、空き Java ヒープ・メモリーが減少している間) に取得した 2 つのメモリー・ダンプ (プライマリー・ダンプおよびベースライン・ダンプ) を比較するために使われます。比較分析は、単純なメモリー・リーク検出との併用に適しています。比較分析では、プライマリー・ダンプは、(構成済みの最大ヒープ・サイズの大部分を消費して) メモリー・リークがかなり進行した後で取得したダンプを参照します。ベースライン・ダンプは、メモリー・リークによってヒープがまだあまり消費されていないときに早期に取得したヒープ・ダンプを参照します。ダンプ間のヒープ使用量が多いほど、分析結果はよくなります。

    比較分析の手法では、構成データ型のインスタンス数が大幅に増加している大規模なデータ構造セットを特定します。データ構造は、それぞれのダンプにグループ化されてから、大幅に増加している疑いがあるデータ構造を特定するために、プライマリー・ダンプとベースライン・ダンプで突き合わせおよび比較が行われます。この手法は、リークが発生している疑いのあるデータ型 (より低レベルの粒度であるストリングなど) を特定するのではなく、より高レベルの粒度でリークが発生している疑いのあるデータ構造を特定します。この点で、今日の市場での数多くの分析ツールで使われている、ヒープ・ダンプを区別する基本的な手法とは異なります。例えば、MDD4J は、単にソースのどこかでとても多くのストリングのリークが発生していると伝えるのではなく、特定のコンテナー (特定の EJB オブジェクトなど) でとても多くのストリングのリークが発生していることを通知します。疑いのあるデータ構造を特定することで、メモリー・リークの根本原因をよりよく理解することができます。図 3 のツリー・ビューには、データ構造の例が示されています。ここでは、ストリング・オブジェクトでリークが発生している点だけでなく、クラス内の HashSet から名前 MyClass によって参照されていることも確認できます。

分析結果は、次の機能を備えた対話式の Web ベースのユーザー・インターフェースに表示されます。

  • 分析結果、ヒープ・コンテンツ、サイズ、および増大の概要をリストする。

  • 比較分析および単一ダンプ分析のために、それぞれヒープ使用量の増大の原因、および大きなサイズのヒープの原因となっている疑いのあるデータ構造、データ・タイプ、およびパッケージをリストする。

  • 所有権コンテキスト・ビューには、フットプリントの主な原因、および主なフットプリントの原因の要約セットのを重要な構成データ・タイプの所有権の関係が示されます。

  • 対話式のツリー・ビューでのブラウズ機能は、ヒープ・ダンプの関連する部分を表示し、ヒープ内の疑いのあるコンテナー・オブジェクトおよびコンテナー・オブジェクトの子オブジェクトに対するすべての着信参照 (ツリーに表示される参照は 1 つだけで、残りは別個に表示されます) および発信参照が到達サイズに応じてソートされて示されます。

  • サスペクト・リストから所有権コンテキスト、および目次ビューから参照ビューへのナビゲーション機能。

  • フィルター機能があり、列がソートされているメモリー・ダンプ内のすべてのオブジェクトおよびデータ型の表形式のビュー。

MDD4J ツールは、数多くの既存のツールからの最高の機能を組み合わせたものです。比較分析の手法は、Leakbot 研究プロジェクト (参考文献を見てください) を基にしています。単一ダンプ分析機能は、alphaWorks からダウンロード可能な HeapAnalyzer ツール (参考文献を見てください) でも使用される分析手法を使用します。表形式のビューは、コマンド・ライン・ツール HeapRoots (参考文献を見てください) からの機能を基にしています。

WebSphere Application Server V6.1 では、Java 用メモリー・ダンプ診断ツール (バージョン 1.0) が、システム管理者用のスタンドアロン・ツールである IBM Support Assistant ツール (バージョン 3.0) にパッケージされています。このツールは、オフライン分析のためにヒープ・ダンプを転送できる任意のマシン上の WebSphere Application Server から別個にインストールすることもできます (参考文献を見てください)。(IBM Support Assistant バージョン 3.0 から MDD4J バージョン 1.0 を起動する方法については、参考文献を見てください。)

IBM Support Assistant のダウンロード後は、Updater のメカニズムを使って、MDD4J を別個に追加することができます。IBM Support Assistant の Updater のビューで「新規製品とツール (New Products and Tools)」=>「共通のコンポーネントおよびツール (Common Component and Tools)」を選択します (また、WebSphere Application Server V6.0 または V5.0 製品プラグインもインストールされていることを確認してください)。

この新規バージョンの MDD4J (バージョン 1.0) は、前のバージョン (バージョン 0.97a) に対して、スケーラビリティー関連する数多くの改善点、64 ビットのヒープ・ダンプに対するサポートが追加されています。(この前のバージョンの MDD4J は、developerWorks のテクノロジー・プレビューとしてダウンロードできます。参考文献を見てください。)

次の例は、単純なメモリー・リークが発生している Java アプリケーションに関するメモリー・リーク分析結果を示しています。このサンプル・アプリケーションでは、静的な HashMap へのストリング・オブジェクトのリークが発生しています。このサンプル・アプリケーションでは、静的な HashMap へのストリング・オブジェクトのリークが発生しています。単純なリーク検出は、早い段階でリークの存在を特定して、適切なヒープ・ダンプを自動的に生成することができます。その後、これらのダンプは、MDD4J で比較分析を使ってオフラインで分析されます。図 2、3、および 4 には、メモリー・リークのサスペクトを示す分析結果が表示されています。

図 2. MDD4J分析結果のメモリー・リークのサスペクト
MDD4J分析結果のメモリー・リークのサスペクト
図 3. MDD4J での疑いのあるデータ構造の参照
MDD4J での疑いのあるデータ構造の参照
図 4. MDD4Jのフットプリント分析
MDD4Jのフットプリント分析

まとめ

WebSphere Application Server V6.1 を使うと、システム管理者は、バイトコード挿入または接続されたエージェントを使わずに、実稼働環境で発生しているメモリー・リークの通知を早期に受け取ることができます。単純なメモリー・リーク検出は、パフォーマンスへの影響を最小にするよう設計されており、正確な分析結果を出すことができるように、適切なときに自動的にヒープ・ダンプを生成する機能を備えています。

手動でまたはメモリー・リーク検出を活用して生成したヒープ・ダンプは、MDD4J を使ってオフラインで分析することができます。システム管理者は、このツールを使うと、問題を適切なコンポーネントに割り当てることができ、開発者は自分のマシンで分析結果を簡単に再現できます。MDD4J は、コード内でリークが発生しているデータ構造を判別するために、リークが発生している候補を特定して、ヒープおよび所有権のチェーンを参照し、開発者および問題判別コンサルタント用のツールを提供します。

このテクノロジーは、Java ヒープ・メモリー・リークの検出と分析の診断に大いに役立ち、適切なシステム・テスト手順または実動システムのいずれかとともに使用することができます。


謝辞

記事をレビューしてくださった Daniel Julin および Stan Cox、指導力を備え、イノベーションを促進している LeakBot プロジェクトの研究主任である Nick Mitchell、MDD4J の開発時に支援および協力してくださった Mark T Schleusner に感謝いたします。

参考文献

学ぶために

製品や技術を入手するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=WebSphere, Java technology
ArticleID=267917
ArticleTitle=WebSphere Application Server でメモリー・リークを検出して分析する: パート 1: メモリー・リークの概要
publish-date=06282006