(57)【要約】      （修正有）【課題】ユーザが正常と考えていない参照関係を持つオブジェクトを、指示された条件を用いて自動的に見つけ出し、ガベージコレクション機能で回収されない理由を提示して、メモリリーク原因調査の時間を短縮する。【解決手段】実行中のプログラムが利用可能なメモリ領域中の、ある領域に生成されたデータを検査し、設定された異常状態に該当するデータがあるかをチェックし、ある場合はそのデータに対する参照関係を許可された参照関係と許可されない参照関係に分類する。メモリ中のデータの異常状態や、或るデータに対する参照関係の分類規則は、プログラム実行前にあらかじめ設定するか、プログラム実行中に設定してもよい。最終的に、許可されていない参照関係情報を警告として出力する。また、分類した参照関係を、データ間の参照関係を表すグラフとして表示し、データ間の参照関係を許可／不許可に応じた見せ方として、ユーザの視覚に直接訴える。【選択図】図１
2007004413.tif 000002
【特許請求の範囲】
【請求項１】
コンピュータのメモリに格納されたデータに関して、データ相互間の参照関係をたどることができるプログラミング言語で記述されたプログラムを実行する場合において、
コンピュータのメモリに格納されたデータのタイプ、格納先の条件、及び、メモリリークデータの抽出処理を開始するための分岐条件を読み込む第１のステップと、
データの格納先、タイプにより、前記分岐条件を用いて、メモリリークデータの抽出処理を行うか否かをチェックする第２のステップと、
前記抽出処理を行う場合において、
データタイプ別参照条件を読み込む第３のステップと、
第２のステップでメモリリークデータの抽出処理の対象となったデータについて、前記参照条件と比較する第４のステップと、
を有するメモリリークの検出方法。
【請求項２】
請求項１に記載のメモリリークの検出方法において、
前記分岐条件は、同一データ種別を表すデータが1つ存在する状態であることであるメモリリークの検出方法。
【請求項３】
請求項１に記載のメモリリークの検出方法において、
第３のステップに代えて、前記参照条件をあらかじめ設定するメモリリークの検出方法。
【請求項４】
請求項３に記載のメモリリークの検出方法において、
第２のステップにおける抽出処理を行わない場合において、メモリリークデータの抽出処理の対象とならなかったデータについて、前記参照条件と比較するステップを有するメモリリークの検出方法。
【請求項５】
請求項１に記載のメモリリークの検出方法において、
データのタイプ、格納先の条件、分岐条件、データタイプ別参照条件、及び、抽出処理の対象となったデータのうち、少なくともいずれか１つを表示するメモリリークの検出方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、コンピュータプログラムが使用するデータ記憶領域の調査方法とその情報提示方法に係り、特に、オブジェクトへの参照関係の分類を利用し、メモリリーク原因を検出し、その情報を提示する方法に関する。
【背景技術】
【０００２】
コンピュータプログラムが期待通りの性能を示さない原因の一つとして、プログラムが使用するデータ記憶領域が増え続ける、メモリリークという現象が挙げられる。
通常、プログラムを実行する際に生成されるデータは、ヒープ領域と呼ばれる記憶領域に配置される。ヒープ領域とは、プログラム実行中に使用されるメモリ領域の一種であり、プログラムに入力されたデータなど、格納領域の大きさが動的に決定されるデータの格納に利用される。
データを格納する際には、格納するデータの大きさに基づいた格納用領域確保が必要であり、そのデータが不要になった際には、確保した格納用領域を解放する操作が必要である。確保した領域の解放操作が適切に行われなかった場合や、実行系から未解放データが見えなくなってしまった場合、プログラムが使用しているメモリ領域が増加し続ける状態、すなわちメモリリークが発生する。
メモリリークが発生すると、プログラムによる使用メモリ領域が増加し続け、ページングの多発による性能低下や、メモリ資源枯渇によるプログラム停止を余儀なくされる。
【０００３】
メモリリークの発生パターンは、ヒープ領域中のデータ領域解放の方法によって、大きく２種類に分けることができる。1つは、C言語やC++言語のように、領域解放の操作を明示的に行う言語におけるメモリリークであり、もう1つは、Java言語のように領域解放を暗黙的に行う言語におけるメモリリークである。
C言語やC++言語のように、ヒープ領域における領域解放を明示的に指示する言語の場合、プログラム実行中のデータ領域確保および解放を監視し、解放されていない領域をメモリリークの原因データと見なし、その発生箇所を特定するための技術が開発されている。
【０００４】
一方、Java言語のようにデータ領域解放を暗黙的に行うプログラミング言語では、不要になったデータ格納用領域を回収する、ガベージコレクション機能が利用可能である。ガベージコレクション機能は、データの参照関係から外れたデータを回収する機能である。このため、プログラムミスによってプログラム作成者が予期しない参照が生じている場合には、本来は不要なデータであっても、ガベージコレクション機能の回収対象とならず、不要なデータがメモリ中で増え続けるメモリリークが発生する。
このようなメモリリークが発生した場合、その原因はプログラム作成者が予期していないミスであるため、原因究明は非常に困難である。そのため、メモリリークが疑われるプログラムの実行中に、複数のメモリスナップショットを取得し、そのスナップショットを利用してメモリ中で使用量が増加しているデータ群を示し、それらに対する参照関係を図示することによって、メモリリーク発生箇所の発見を補助するための技術が開発されている（特許文献1、特許文献2、非特許文献1参照）。なおJavaは米国Sun Microsystems, Inc.及びその他の国における商標または登録商標である。
【０００５】
【特許文献１】米国特許公報６,１６７,５３５号
【特許文献２】米国特許公報６,３７０,６８４号
【非特許文献１】Nick Mitchell and Gary Sevitsky. Leakbot: An Automated and Lightweight Tool for Diagnosing Memory Leaks in Large Java Applications. In ECOOP2003, LNCS 2743. Springer-Verlag, 2003.
【発明の開示】
【発明が解決しようとする課題】
【０００６】
プログラム実行中に生成されるデータの数は膨大であり、その参照関係も複雑なものとなる。そのため、従来技術においてメモリリークの発生が疑われるものとして検出されるデータの数や、メモリリークの発生原因候補として指摘される箇所は膨大な数になりがちであり、それらの候補の中から本当のメモリリークの原因に到達するまでには長い調査時間を要している。
【課題を解決するための手段】
【０００７】
本発明では、実行中のプログラムがヒープメモリ領域中に生成したデータを検査し、設定された状態に反するデータが存在する場合には、そのデータに対する参照関係を、許可された参照関係と許可されない参照関係に分類する。
許可されていない参照関係情報を警告として出力することによって、異常な状態にあるデータが、ガベージコレクション機能で回収されない理由を提示する。
【発明の効果】
【０００８】
ある領域中の特定のオブジェクトとの参照関係から、ユーザが正常と考えていない参照関係を持つオブジェクトを、指示された条件を用いて自動的に見つけ出し、ガベージコレクション機能で回収されない理由を提示することによって、メモリリーク原因調査の時間を短縮できる。
また、メモリ状態の検査は一度でよいため、複数のスナップショットを必要とする従来のメモリリーク検出手法よりも低オーバヘッド化が実現できる。
【発明を実施するための最良の形態】
【０００９】
データと、その生成領域に対して設定した状態規則に反したデータを見つけることで、メモリリークの危険性を検出する。データに対して設定した参照規則に反した参照関係からメモリリーク原因を抽出し、その結果を示す。これにより、膨大な数の生成データからメモリリークが発生していることを自動的に検出し、その原因を指摘するという目的を達成した。
【実施例１】
【００１０】
本発明に係るメモリリーク検出手法の一実施形態について、以下、図面を用いて説明する。
図1は、本発明を実施するコンピュータ100の構成を示す図である。このコンピュータ100は、各種処理を実行するプロセッサ110と、プロセッサ上で実行されるJava仮想マシン111が用いるメモリ121を含むメモリ120と、記憶装置101と、表示装置150を備えている。
Java仮想マシン111はJavaプログラム112を実行することができ、その実行の際に生成されるデータは、Java仮想マシン内メモリ121のうち通常のヒープ領域122もしくはPermanentヒープ123のどちらかに生成される。Java仮想マシンにはガベージコレクション機能があり、どこからも参照されなくなったデータを自動的に解放する。その効率化の一手段としてメモリ領域を役割に応じて分割し、1回のガベージコレクションによるオーバヘッドを小さくしている。
【００１１】
Java仮想マシンにおけるメモリ領域の分割には、データの生存期間の長短を用いており、通常のヒープ領域122には短期間で不要になりやすいデータ、Permanentヒープ領域123には長期間必要とされるデータが格納される。短期間で解放される主なデータとしては、プログラム実行において生成されるプリミティブなデータが挙げられる。また、長期間解放されないデータとしては、クラスそのものを表すデータが挙げられる。
本実施例では、このクラス表すデータについてのメモリリーク原因の抽出について説明している。
【００１２】
プロセッサ110は、メモリリーク検出プログラム113を実行する機能も備えている。メモリリーク検出プログラム113は、機能的にはメモリリーク発生の可能性を検知するメモリリーク可能性検出処理114と、メモリリーク発生の可能性がある場合に実際にメモリリークデータを抽出するメモリリークデータの抽出処理115と、その結果を表示する結果表示処理116の機能を持ち、その結果は表示装置150で表示される。記憶装置101には、Java仮想マシン111が使用するメモリ121のメモリイメージや、メモリリークの危険性検出に用いる状態条件102、メモリリーク原因の調査に用いる参照条件103を格納することができる。
【００１３】
図2に示すフローチャートに従って、メモリリーク可能性検出処理114の動作を説明する。
まず処理301で、データタイプ及び格納先の状態条件102を記憶装置101から読み込む。データタイプおよび格納先の状態条件については次段落で詳しく説明する。次に、処理302で実行中のJava仮想マシンのメモリイメージを取得し、記憶装置101に格納する。この際、処理301で読み込んだ条件によって、取得するメモリ領域を通常のヒープ122のみ、もしくはPermanentヒープ123のみにすることもできるし、両方をあわせたJava仮想マシン内メモリ121全体のイメージを取得することもできる。次に、処理303では、処理302で取得したメモリイメージを記憶装置101から読み込み、Java仮想マシン内のメモリ状態を調査する。この際調査する項目は、処理301で読み込んだ条件に関するものである。そして、処理304にて、処理301で読み込んだ条件との比較操作を行い、条件に反しているデータが存在する場合は、メモリリークデータの抽出処理115に進む。ない場合はそこで調査を打ち切る。
【００１４】
処理301で記憶装置101から読み込む条件102には、データのタイプ及びその格納先と、格納先でのデータの状態規則など、データタイプとその格納先が正常な状態である場合に満たすべき条件を記述することができる。データのタイプとは、そのデータ自体の種別であり、Javaではクラスやインスタンス、配列を指定することが考えられる。また、格納先は調査すべき領域であり、Javaの場合は通常のヒープ領域、permanentヒープ領域、スタックなどがこれにあたる。格納先でのデータの状態条件には、データのタイプとその格納先での正常な条件を設定することができ、同一クラスの数やクラスデータの合計数、データのサイズなどの閾値を設定することができる。
【００１５】
図3は、図2の処理301で読み込むデータタイプ及び格納先状態条件102の例である。Typeは対象とするデータタイプであり、この例ではclass、すなわちクラスデータを指している。RegionはTypeで示されたデータタイプが格納される先であり、この例ではpermanentヒープ123である。Condition以降の行は、Regionで示される領域内のTypeで示されるデータタイプに関する正常な条件を表しており、この例では、同一クラスを表すクラスデータが1つの場合は正常ということを示している。1つのデータタイプについて複数の条件がある場合はここに羅列する。また、異なるデータタイプに対する条件が存在する場合はこれらの表現を繰り返し記述する。
【００１６】
図4に示すフローチャートは、処理304における比較操作の流れを表している。まず、処理401で未処理データを1つ選択し、処理402及び403で図3に示す条件のうちデータ生成先とデータタイプを確認する。処理401で選択したデータがRegion及びTypeに該当するデータである場合は処理404に進み、該当しない場合は処理406に進む。処理404では、図3におけるCondition以降の行に書かれている条件との比較操作を行う。条件に反するかどうかを処理405でチェックし、条件に反するデータがある場合は、メモリリークデータの抽出処理115に進む。最後に処理406では、まだ調査していないデータがあるかどうかを調べ、ある場合は処理401に戻り、ない場合は処理を終了する。
【００１７】
図5に示すフローチャートに従って、メモリリークデータの抽出処理115の動作を説明する。まず、処理311で、記憶装置101からデータタイプ別参照条件103を読み込む。データタイプ別参照条件については次段落で詳しく説明する。次の処理312では、処理304で検出された異常データの参照関係を処理311で読み込んだデータタイプ別参照条件と比較する。もしメモリリーク可能性検出処理114の処理302で、Java仮想マシンから取得したメモリイメージが部分的であり、処理312での比較操作で必要なデータが不足している場合は、再度メモリイメージを取得することで対応する。
処理311で記憶装置101から読み込むデータタイプ別参照関係の条件103には、指定するデータタイプ、所属クラス名、そのデータを参照しているデータのタイプや数などについて、そのデータが正常なデータである場合に満たすべき条件を設定することができる。また、条件を設定するデータに関連する別項目も設定することができる。例えば、指定データの所属クラスを読み込んだクラスローダに関する条件である。
【００１８】
図6は、図5の処理311で読み込むデータタイプ別参照関係の条件の記述例である。この例では、Typeは指定するデータタイプ、Classは所属クラス名、Ref_numはそのクラスを直接参照しているデータの数、Loader_refはそのクラスのクラスローダに対するクラス以外からの参照の有無である。なお、条件式のAND、OR関係はC言語の論理式のように記述しており、この例ではRef_numとLoader_refについては、OR条件の関係にある。また、この例のようにTypeがclassそのものである場合は、classはそのクラスデータが表すクラスと解釈する。Javaでは、クラスデータとクラスローダは相互参照の関係にあるため、クラスデータを参照しているデータの数は必ず1以上となる。この例は、Caクラスデータへの参照が1つ、もしくはCaクラスのクラスローダへの直接参照があれば、注目しているCaクラスのクラスデータは正常という条件を示している。
【００１９】
図7に示すフローチャートは、処理312での参照条件との比較操作を表している。まず、処理411で、処理304で異常と判定されたデータの1つを選択する。次の処理412及び413において、処理411で選択したデータが図6に記述されたデータタイプTypeと所属クラスClassに該当するかどうかを調べ、該当する場合は処理414に、該当しない場合は処理416に進む。処理414では、図6に記述された条件のうち、Type及びClass以外の条件との比較を行う。処理414の結果、条件に反するデータであるかどうかを処理415でチェックし、条件に反するデータである場合は結果表示処理116へ、正常なデータである場合は処理416に進む。処理416では、処理304で異常と判定されたデータがまだあるかどうかをチェックし、ある場合は処理411に戻り、ない場合は終了する。
【００２０】
図8は、Javaにおけるクラスデータとクラスローダの参照関係を示している。図8上部の正常なクラスデータとクラスローダの参照関係では、クラスローダとクラスデータは相互参照関係にあり、他のデータからクラスローダへの参照がある状態である。これは正常な参照関係の一例であり、これ以外の参照関係が全て異常というわけではない。図8下部の異常なクラスデータとクラスローダの参照関係の例では、正常な参照関係と比較して、(1)クラスデータ501-1、501-2のように同一クラスを表す異なるクラスデータがPermanent領域内に存在する、(2)クラスローダ502にクラスデータからの参照503-1、503-2、503-3以外の参照がなく、さらにクラスデータ501-1に対して他のデータ505からの参照504がある、という差がある。クラスデータがメモリリークしている場合に、図8下部のような状態になることが多いが、この状態になれば必ずメモリリークしているということではない。上記(1)はクラスデータがメモリリークしている可能性を表し、上記(2)はなぜクラスデータ501-1がガベージコレクション機能で解放されずにメモリ上に存在するのかという理由を示している。図3で示される条件は上記(1)を検出し、図6で示される条件は上記(2)を検出することができる。
図8下部の異常なクラスデータとクラスローダの参照関係の例に対して、図3で示す条件を適用する。まず処理401でクラスデータ501-1を選択し、処理402及び403においてクラスデータ501-1の格納領域とデータタイプを調べる。図3においては、格納領域としてPermanent領域、データタイプとしてクラスが指定されており、クラスデータ501-1はこれらの条件を満足するので、処理404に進む。処理404では図3におけるCondition以降に指定されている「same:num=1（同一データの数は1つ）」という条件との比較を行うが、クラスデータ501-1と501-2は同一クラスを表すデータであるため、条件に違反していることがわかる。よって、処理405からメモリリークデータの抽出処理115に進む。他のデータについては、クラスデータ507、508も同様に異常と判定される。次に、これらの異常と判定されたデータに対して、メモリリークデータの抽出処理115の処理312において、図6に示すデータタイプ別参照条件を適用する。処理411では処理304で異常と判定されたクラスデータのうちの1つ501-1を選択する。処理412及び413でデータタイプ及びクラスを確認する。図6の参照条件ではデータタイプはクラス、所属クラスはCaとなっており、クラスデータ501-1はこれを満足するため、処理414に進む。処理414では、図6における残りの条件「Ref_num=1（参照数は1）」もしくは「Loader_ref=yes（Caクラスのクラスローダへの他のデータからの参照がある）」との比較を行うが、クラスデータ501-1はこれらの条件を両方とも満足していないため、判定処理415から結果表示処理116に進む。残りの異常データ507、508は、参照条件のうちのRef_num=1を満足しているため、正常データと見なされる。
【００２１】
図9は、図1の結果表示処理116において表示装置150に表示されるメモリリーク検出結果の出力例である。この例では、図1のメモリリーク可能性検出処理114及びメモリリークデータの抽出処理115において読み込まれた図3及び図5に示す条件に反するデータとその参照関係を示している。結果表示処理116は、図3及び図6の条件に反する参照関係を示すことによって、その原因を直感的に示す処理であり、この例では、図8で異常と判定されたクラスCaへの参照関係504の詳細を示している。
この表示によって、どの参照があるべきではないのかをユーザが調べることができる。Permanentヒープ中に存在するデータのうち、図3の条件より異常とみなされるデータの1つがclass name 201で示すCaクラスのデータであり、その数は図中num200で示される2である。また、図5の条件より抽出した異常な参照関係を表示202として示している。異常な参照関係の表示202では、異常データであるCaクラスのデータを起点として、参照関係上の上位データを参照関係を遡って表示している。
この例では、図8中のデータ505(Obj2)は図9における210に、データ506(Obj3)は211に対応している。各データには、そのデータからの参照を表すフィールドの型宣言203と名前204、そのデータのタイプ205が表示されている。例えば、図9における表示211は、図8のINSTANCEタイプのデータ506から、フィールド型java/lang/Object、フィールド名elementDataと宣言されたフィールドによって、図8中のデータ505(Obj2)への参照を示している。
データタイプによっては、フィールド型宣言203と名前204が存在しないことがあるが、その場合は表示210のように型宣言及び名前欄を空欄とする。また、全ての参照関係を出力すると情報が多くなりすぎるため、参照元データ数が1より大きいデータが出現するまで出力することも可能である。このような参照関係を全ての異常データについて表示することによって、メモリリーク原因となっている箇所の特定を補助することができる。また、この例は文字ベースの結果表示例だが、図8に示すようなオブジェクト参照グラフをグラフィカルユーザインタフェースによって表示し、分類した参照関係やデータ間の参照関係の許可／不許可に応じて表示を差別化することにより、直感的な情報表示を行うことも可能である。
【００２２】
なお、本実施例では、Java仮想マシンのメモリ状態を調査するために、メモリイメージを記憶装置101に出力し、メモリリーク検出プログラム113が記憶装置101上のデータを読み込む例を示したが、Java仮想マシン111内にメモリ状態を調べるインタフェースを用意し、記憶装置を経由せずに異常を検知するようにすることも可能である。
【産業上の利用可能性】
【００２３】
メモリリーク現象を減らし、コンピュータプログラムが期待通りの性能を示すコンピュータを調整する産業に利用できる。
【図面の簡単な説明】
【００２４】
【図１】本発明を用いたシステムの全体図
【図２】メモリリークの可能性検出のフローチャート
【図３】メモリリーク可能性検出で用いる条件の例
【図４】メモリリーク可能性検出における条件比較のフローチャート
【図５】メモリリークデータ抽出のフローチャート
【図６】メモリリークデータ抽出で用いる条件の例
【図７】メモリリークデータ抽出における条件比較のフローチャート
【図８】Javaにおけるクラスデータとクラスローダの参照関係
【図９】メモリリークデータへの参照関係の出力例
【符号の説明】
【００２５】
100…コンピュータ
101…記憶装置
102…データタイプ及び格納先の状態条件
103…データタイプ別参照条件
110…コンピュータ内のプロセッサ
111…Java仮想マシン
112…Javaプログラム
113…メモリリーク検出プログラム
114…メモリリーク可能性検出処理
115…メモリリークデータの抽出処理
116…メモリリークデータの抽出結果の表示処理
120…コンピュータ内のメモリ
121…コンピュータ内のメモリにおいて、Java仮想マシンが使用するメモリ領域
122…Java仮想マシンが使用するメモリ領域中の通常のヒープ領域
123…Java仮想マシンが使用するメモリ領域中のPermanentヒープ領域
150…表示装置
【図１】
2007004413.tif 000003
【図２】
2007004413.tif 000004
【図３】
2007004413.tif 000005
【図４】
2007004413.tif 000006
【図５】
2007004413.tif 000007
【図６】
2007004413.tif 000008
【図７】
2007004413.tif 000009
【図８】
2007004413.tif 000010
【図９】
2007004413.tif 000011