(57)【要約】【課題】長時間のプログラム停止を伴うガベージコレクションを行わず、かつ、追加のＡＰＩを用いないメモリ管理を実現することを課題とする。 【解決手段】本発明は、コンピュータ１０１内のプロセッサ１０２により実行されるＪａｖａプログラム１０４によって、ガベージコレクションの対象となるＪａｖａヒープメモリ１１１と、ガベージコレクションの対象とならない外部ヒープメモリ１１２と、の領域を確保可能なメモリ１０３の管理を行うメモリ管理方法である。  外部ヒープメモリ１１２に関して、配置された全データ、あるいは、全データのうちの参照関係の起点データに対して、外部ヒープメモリ１１２以外に配置されたデータからの参照がないと判定した場合、外部ヒープメモリ１１２を解放可能と判定する。【選択図】図１
2010225033.tif 000002
【特許請求の範囲】
【請求項１】
コンピュータ内のプロセッサにより実行されるプログラムによって、ガベージコレクションの対象となる対象メモリと、ガベージコレクションの対象とならない対象外メモリと、の領域を確保可能なメモリの管理を行うメモリ管理方法であって、
前記対象外メモリに関して、配置された全データ、あるいは、前記全データのうちの参照関係の起点データに対して、当該対象外メモリ以外に配置されたデータからの参照がないと判定した場合、当該対象外メモリを解放可能と判定する
ことを特徴とするメモリ管理方法。
【請求項２】
請求項１のメモリ管理方法において、前記対象外メモリに配置したデータの情報を、前記プログラムの起動オプションまたは外部入力ファイルを用いて取得する
ことを特徴とするメモリ管理方法。
【請求項３】
請求項１のメモリ管理方法において、前記対象外メモリに関する解放可能か否かの判定を、前記ガベージコレクションの終了時に行う
ことを特徴とするメモリ管理方法。
【請求項４】
請求項１のメモリ管理方法において、前記対象外メモリに関する解放可能か否かの判定を、前記プログラムの起動オプションまたは外部入力ファイルに記述されたメモリ使用量に関する閾値を実際の前記メモリの使用量が超えた場合に行う
ことを特徴とするメモリ管理方法。
【請求項５】
請求項１のメモリ管理方法において、前記対象外メモリに関して、配置された全データのうちの参照関係の起点データに対して、当該対象外メモリ以外に配置されたデータからの参照がないと判定した場合、当該メモリを解放可能と判定するとき、
前記起点データを参照するデータが当該対象外メモリ以外に配置されていた場合、当該データの必要性を判定し、当該データを必要性がないと判定したとき、当該データから前記起点データへの参照をないものと見なし、当該対象外メモリを解放可能と判定する
ことを特徴とするメモリ管理方法。
【請求項６】
請求項５のメモリ管理方法において、前記必要性の判定を、前記ガベージコレクションの終了時に行う
ことを特徴とするメモリ管理方法。
【請求項７】
請求項５のメモリ管理方法において、前記必要性の判定を、前記プログラムの起動オプションまたは外部入力ファイルに記述されたメモリ使用量に関する閾値を実際の前記メモリの使用量が超えた場合に行う
ことを特徴とするメモリ管理方法。
【請求項８】
請求項５のメモリ管理方法において、当該データの必要性を判定するとき、
前記対象メモリの領域を２つ以上の領域に分割し、分割領域ごとに、他の分割領域のデータからの参照について調べ、直接的もしくは間接的に参照される可能性があるデータ以外のデータを必要性がないと判定する
ことを特徴とするメモリ管理方法 。
【請求項９】
請求項８のメモリ管理方法において、前記分割領域のうち、前記対象外メモリに配置されたデータを参照するデータが配置されている領域を、前記必要性を調べる領域として選択する
ことを特徴とするメモリ管理方法。
【請求項１０】
請求項８のメモリ管理方法において、前記対象メモリの領域を２つ以上の領域に分割する際の分割領域のサイズを、前記プログラムの起動オプションまたは外部入力ファイルに記述している
ことを特徴とするメモリ管理方法。
【請求項１１】
請求項８のメモリ管理方法において、前記対象メモリの領域を２つ以上の領域に分割した後、相互参照関係にある２つのデータが異なる分割領域に存在する場合に、少なくともいずれかのデータを移動することで、当該２つのデータが同一の分割領域にあるようにする
ことを特徴とするメモリ管理方法。
【請求項１２】
請求項１のメモリ管理方法であって、前記プログラムの起動オプションまたは外部入力ファイルの情報を読み込み、その結果を用いて前記対象外メモリの領域を生成する
ことを特徴とするメモリ管理方法。
【請求項１３】
ガベージコレクションの対象となる対象メモリと、ガベージコレクションの対象とならない対象外メモリと、の領域を確保可能なメモリと、
前記対象外メモリに関して、配置された全データ、あるいは、前記全データのうちの参照関係の起点データに対して、当該対象外メモリ以外に配置されたデータからの参照がないと判定した場合、当該対象外メモリを解放可能と判定するプロセッサと、
を備えることを特徴とするコンピュータ。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、コンピュータプログラムにおけるメモリ管理の技術に関する。
【背景技術】
【０００２】
コンピュータプログラムを開発する上で、プログラム実行時に利用するメモリ領域の確保・解放処理は、プログラム開発者の手を煩わせる項目のうちの１つであり、プログラム（動作）不良を起こしやすい項目であることが知られている。例えば、一般的なプログラミング言語であるＣ／Ｃ＋＋言語では、プログラムの実行に必要なメモリ領域の確保や解放処理をユーザが明示的に記述する必要があり、これに起因するプログラム不良が多発している。
【０００３】
プログラム不良の例としては、確保したメモリ領域の解放し忘れで発生するメモリリークや、解放済みメモリ領域に対する不正な参照（参照先に本来参照すべきデータが存在しないこと ）が挙げられる。プログラム開発者は、メモリの利用状態を常に気に留めながらプログラムを開発しなければならないが、複数人でのプログラム開発や、プログラムコードの肥大化によって、全てのメモリの確保・解放処理を正確に記述するのは困難になりつつある。
【０００４】
これを解決する手段として、プログラム中でのメモリ管理を自動化するガベージコレクタの利用が挙げられる。ガベージコレクタを利用したメモリ管理を行う言語処理系の１つであるＪａｖａ（登録商標）には、プログラム実行時のメモリ確保用ＡＰＩ（Application Program Interface）は用意されているが、解放用ＡＰＩは存在しない。プログラム実行の過程で確保したメモリ領域の解放は、Ｊａｖａプログラムを実行するＪａｖａ仮想マシンに実装されたガベージコレクタが行っている。そして、ガベージコレクタが実行するガベージコレクション（以下、「ＧＣ」ともいう。）では、全てのＪａｖａプログラム実行スレッドを停止させて、不要なデータを回収する実装形態をとることが多い。
【０００５】
Ｊａｖａ仮想マシンがＧＣを起動するのは、Ｊａｖａプログラム上で生成されるデータ（Ｊａｖａオブジェクト）を格納するＪａｖａヒープメモリの使用量がある閾値を超える直前であるが、プログラム実行によるメモリ使用量をユーザが見積もるのは困難であり、この閾値を越えるタイミングを予見することも難しい。よって、この閾値を越えたことによるＧＣの起動をユーザが予見することも困難であるため、実行中のプログラムは不定期に停止することになる。
【０００６】
さらに、Ｊａｖａ仮想マシンにおけるＧＣの実装方式として採用されていることが多い世代別ガベージコレクションでは、停止が短時間で済むＧＣと、長時間の停止を要するＧＣが発生するが、次にどちらのＧＣが発生するかを予見することは困難である。近年、Ｊａｖａシステムがサーバサイドや組み込み分野（産業機器や家電製品など）で用いられるようになってきたが、予期しないＧＣによる長時間のプログラム停止が発生するとシステム全体の応答がなくなることが問題視されるようになってきている。
【０００７】
本問題を解決する方法が、例えば、非特許文献１，２に開示されている。これらの非特許文献１，２に開示されている方法では、Ｊａｖａ仮想マシンによるＧＣの対象であるヒープメモリ（以下、「Ｊａｖａヒープメモリ」という。）の他に、ＧＣの対象外であるヒープメモリ（以下、「外部ヒープメモリ」という。）を有する。外部ヒープメモリとは、プログラムによりメモリ管理が可能なメモリ領域である。すなわち、外部ヒープメモリの確保、オブジェクトの生成及び外部ヒープメモリの解放は、プログラマによるプログラムのソースコード中への記述に従う。
【０００８】
非特許文献１の開示技術における外部ヒープメモリ領域の解放処理では、そのメモリ領域を低オーバヘッドで解放するために、確保したメモリ領域に生成するデータの参照関係に制限を設けている。この制限は、外部ヒープメモリにおいてデータを生成するスレッドが１つもなくなった時点で、このメモリ領域をデータごと解放しても、プログラムの実行には影響がないことを保証するためのものである。このように、プログラムによりメモリ領域管理が可能な領域、すなわちＪａｖａ仮想マシンによるＧＣの対象外である外部ヒープメモリを用い、データの参照関係に制限を設けることにより、Ｊａｖａプログラム実行スレッドの長時間停止の発生を抑制しているが、この制約事項は外部ヒープメモリの利便性を著しく損ねている。
【０００９】
また、データ間の参照関係の制限のため、ユーザは常にデータ間の参照関係に留意しながらプログラミングを行う必要があるが、プログラム規模の肥大化や、ユーザプログラム上で記述されていない暗黙的データ生成（ユーザが記述していないプログラムによるデータ生成 ）の発生により、メモリ上の参照関係の完全な把握は極めて困難であると言える。また、上記制約事項に関する実行時のチェックにより、この制約に違反する参照関係が発生した際は、「例外処理（Ｅｘｃｅｐｔｉｏｎ）」が発生し、プログラムは正常に実行されないことが多い上、本チェック処理により外部ヒープメモリを使わない場合のプログラムの実行性能と比較して、著しい性能低下が発生する点も問題である。
【００１０】
このような問題に対処するために、非特許文献２の開示技術では、オブジェクト間の参照関係に制限を設けずに、外部ヒープメモリ領域を利用できるようにしている。非特許文献１の開示技術における参照関係の制約事項は、外部ヒープメモリ領域の解放を安全に行うためである。一方、非特許文献２の開示技術では、外部ヒープメモリ領域を解放する際、解放対象メモリ領域内のデータと解放対象外メモリ領域のデータとの参照関係を調査し、解放対象メモリ領域における後の実行に必要なデータを解放対象外メモリに移動させる。これによって、その解放対象メモリ領域の解放がプログラムの実行に支障をきたさないことを保証した上で、解放対象メモリ領域を解放する。これにより、データ間の参照関係を気にすることなく外部ヒープメモリ用ＡＰＩを利用できる他、参照関係の調査はメモリ領域解放時のみとなるため、実行時チェックのオーバヘッドも生じない。
【００１１】
図１３は、外部ヒープメモリをＡＰＩで利用する場合のプログラムを示す図である。図１３に示すプログラムは、Ｌｉｓｔクラスのデータを生成し、このデータからＯｂｊクラスのデータｏ１、ｏ２を参照可能とする例である。元のプログラムでは、Ｌｉｓｔクラスのデータ生成はコメントアウトされている行１３０１で示す実行文にあるようにｎｅｗ演算子を用いるが、外部ヒープメモリを利用するために、行１３０２及び行１３０３で示すような実行文に変更している。
【００１２】
行１３０２は外部ヒープメモリの生成指示の実行文であり、ここでは、ＲｅｆｅｒｅｎｃｅＥｘｐｌｉｃｉｔＭｅｍｏｒｙクラスのデータを生成すると共にＧＣ対象外である外部ヒープメモリを生成する。そして、次の行１３０３で示す実行文において、生成した外部ヒープメモリに対してＬｉｓｔクラスのデータを生成している。また、生成した外部ヒープメモリの解放（削除）の指示の実行文を行１３０４で示す。行１３０４で示す実行文が実行されると、行１３０２で示す実行文によって生成した外部ヒープメモリが解放される。その際、外部ヒープメモリ内データに対して、解放対象の外部ヒープメモリ以外の領域からの参照がある場合、参照されているデータ群を解放対象外のメモリに移動させてから解放する。
【００１３】
なお、外部ヒープメモリへのデータの配置方法は２種類ある。１つはプログラム上のある区間内で生成されるデータを全て外部ヒープメモリに配置する方法であり、もう１つは外部ヒープメモリに関連付けた（配置のための関連付けを行った）データから参照可能なデータのみを外部ヒープメモリに配置する方法である。図１３に示すのは、後者の参照関係を利用してデータを配置するタイプの外部ヒープメモリを利用するための記述である。行１３０３に示す外部ヒープメモリへのデータ生成文を、行１３０２で示す実行文によって生成した外部ヒープメモリへの関連付けと見なす。
【００１４】
図１７は、図１３の行１３０５で示す実行文を実行する直前のメモリとデータのイメージを示す図である。行１３０２で示す実行文によって生成した外部ヒープメモリ１１２内に、行１３０３で示す実行文によって生成したＬｉｓｔクラスのデータｌｉ（符号１７０１）が配置されている。また、Ｊａｖａヒープメモリ１１１内にＯｂｊクラスのデータｏ１（符号１７０２），ｏ２（符号１７０３）が生成されており、その他のデータとして、で示すデータＥ（符号１７０４−１），Ｆ（１７０４−２）も配置されているものとする。データ間の矢印１７０５はデータ間の参照関係を表す。この状態で、図１３の行１３０５で示す実行文を実行すると、データｏ１（符号１７０２）とｏ２（符号１７０３）は外部ヒープメモリ１１２に関連付けたデータｌｉ（符号１７０１）から参照可能となる。この様子を図１８に示す。
【００１５】
図１８では、データｌｉ（符号１７０１）からデータｏ１（符号１７０２），ｏ２（符号１７０３）への参照を矢印１８０１，１８０２で示している。この後、ある契機によって、データｏ１（符号１７０２），ｏ２（符号１７０３）を外部ヒープメモリ１１２に移動させる。ある契機としてはＧＣやメモリ使用量の閾値超過などが考えられる。データｏ１，ｏ２の移動後のイメージを図１９に示す。外部ヒープメモリ１１２に関連付けられているデータｌｉ（符号１７０１）から参照可能なデータｏ１とデータｏ２が符号１９０１と符号１９０２として示すように外部ヒープメモリ１１２に移動している。ここで、行１３０４に示す外部ヒープメモリ１１２の解放のための実行文を実行することを考える。図１９に示す状態のまま外部ヒープメモリ１１２を解放してその内部データを削除してしまうと、データＦ（符号１７０４−２）からデータｏ２（符号１９０２）への参照が不正となってしまい、後の実行結果を保証することができない。
【００１６】
そこで、矢印１７０７のようなＪａｖａヒープメモリ１１１（解放対象外メモリ）から外部ヒープメモリ１１２（解放対象メモリ）への参照がある場合は、外部ヒープメモリ１１２（解放対象メモリ）内の被参照データｏ２（符号１９０２）をＪａｖａヒープメモリ１１１（解放対象外メモリ）に移動（コピー）させる。移動（コピー）させた後の様子を図２０に示す。図２０においては、図１９におけるデータｏ２（符号１９０２）をデータｏ２’（符号２００１）に移動（コピー）させ、データＦ（符号１７０４−２）からの参照の矢印１７０７も新たに矢印２００２としている。データｏ２（符号１９０２）とデータｏ２’（符号２００１）は同一のデータであるため、データＦ（符号１７０４−２）からデータｏ２’（符号２００１）への参照は、データＦ（符号１７０４−２）から元のデータｏ２（符号１９０２）への参照と同様であり、外部ヒープメモリ１１２ごとデータｌｉ（符号１７０１），ｏ１（符号１９０１）及びｏ２（符号１９０２）を削除しても、後の実行結果に影響がないことを保証できる。
【先行技術文献】
【非特許文献】
【００１７】
【非特許文献１】F. Pizlo, J. M. Fox, D. Holmes and J. Vitek, Real-Time Java Scoped Memory: Design Patterns and Semantics, Proceedings of the Seventh IEEE Internal Symposium on Object-Oriented Real-Time Distributed Computing, 2004.
【非特許文献２】足立  昌彦、小幡  元樹、西山  博泰、岡田  浩一、浅香  真司、明示的なメモリ管理機能を備えたＪａｖａ仮想マシンの評価、第７回情報科学技術フォーラム（ＦＩＴ２００８）、２００８年
【発明の概要】
【発明が解決しようとする課題】
【００１８】
外部ヒープメモリへのデータ配置方法として、外部ヒープメモリに関連付けたデータ（例えば図１９のデータｌｉ（符号１７０１））から参照可能なデータ（例えば図１９のデータｏ１（符号１９０１））を配置するタイプの外部ヒープメモリを利用する際には専用ＡＰＩを記述する必要があるが、ＡＰＩを適切に記述するには、プログラムの構造やオブジェクト配置の把握が必要であり、プログラム開発期間の長期化を招く恐れがある。特に、外部ヒープメモリの解放記述に関しては、後の実行で必要である可能性があるデータを、ＧＣ対象メモリ領域を含めた解放対象外領域に移動させるため、不適切な箇所に記述を行うと解放対象領域内のデータの多くが解放対象外領域に流出し、結果として長時間停止を要するＧＣを誘発する恐れがある。
【００１９】
また、ＡＰＩを記述したとしても、そのＡＰＩに対応していない処理系で利用することができず、ポータビリティの低下を招く。さらに、ソースプログラムが配布されていない場合や、ライセンスなどの制約によりプログラムの改変が不可能な場合は、外部ヒープメモリを利用することができないため、適用可能プログラムが少なくなってしまう。
【００２０】
本発明は、前記問題に鑑みてなされたものであり、長時間のプログラム停止を伴うガベージコレクションを行わず、かつ、追加のＡＰＩを用いないメモリ管理を実現することを課題とする。 
【課題を解決するための手段】
【００２１】
本発明は、コンピュータ内のプロセッサにより実行されるプログラムによって、ガベージコレクションの対象となる対象メモリと、ガベージコレクションの対象とならない対象外メモリと、の領域を確保可能なメモリの管理を行うメモリ管理方法である。
対象外メモリに関して、配置された全データ、あるいは、全データのうちの参照関係の起点データに対して、当該対象外メモリ以外に配置されたデータからの参照がないと判定した場合、当該対象外メモリを解放可能と判定することを特徴とする。
その他の手段については後記する。
【発明の効果】
【００２２】
本発明によれば、長時間のプログラム停止を伴うガベージコレクションを行わず、かつ、追加のＡＰＩを用いないメモリ管理 を実現することができる。
【図面の簡単な説明】
【００２３】
【図１】本実施形態のコンピュータと外部記憶装置の構成図である。
【図２】Ｊａｖａのサンプルプログラムの例を示す図である。
【図３】起点データ及びデータ生成メソッド情報の外部入力ファイルへの記述例を示す図である。
【図４】起点データ及びデータ生成メソッド情報の起動オプションへの記述例を示す図である。
【図５】起点データ及びデータ生成メソッド情報の外部入力ファイル及び起動オプションからの読み込みアルゴリズムのフローチャートを示す図である。
【図６】外部ヒープメモリ解放可否判定アルゴリズムのフローチャートを示す図である。
【図７】Ｊａｖａヒープメモリと外部ヒープメモリへのデータ配置例を示す図である。
【図８】ガベージコレクション対象領域の分割を伴うデータ必要性判定アルゴリズムのフローチャートを示す図である。
【図９】Ｊａｖａヒープメモリと外部ヒープメモリへのデータ配置例を示す図である。
【図１０】図９のデータ配置例に図８のフローチャートを適用した後のデータ配置を示す図である。
【図１１】ガベージコレクション対象領域の分割を伴うデータ必要性判定を効率的に実施するアルゴリズムのフローチャートを示す図である。
【図１２】Ｊａｖａヒープメモリと外部ヒープメモリへのデータ配置例を示す図である。
【図１３】外部ヒープメモリをＡＰＩで利用する場合のプログラムを示す図である。
【図１４】Ｊａｖａヒープメモリと外部ヒープメモリへのデータ配置例を示す図である。
【図１５】ガベージコレクション対象領域の分割を伴うデータ必要性判定で必要データの移動を伴うアルゴリズムのフローチャートを示す図である。
【図１６】図１４のデータ配置例に図１５のフローチャートを適用した後のデータ配置を示す図である。
【図１７】図１３の行１３０５で示す実行文を実行する直前のメモリとデータのイメージを示す図である。
【図１８】図１７の状態から図１３の行１３０５で示す実行文を実行した後のメモリとデータのイメージを示す図である。
【図１９】図１８の状態からデータｏ１，ｏ２を外部ヒープメモリに移動した後のメモリとデータのイメージを示す図である。
【図２０】図１９の状態からデータｏ２をＪａｖａヒープメモリに移動した（コピーした）後のメモリとデータのイメージを示す図である。
【発明を実施するための形態】
【００２４】
本発明に係るメモリ管理方法を実施するための形態（以下、実施形態という。）について、図面を用いて説明する。なお、複数の図面にわたっての同一の構成や処理には同一の符号を付し、重複する説明を適宜省略する。また、本実施形態はＪａｖａ言語に対して本発明を適用した場合の説明となっているが、ガベージコレクション機能を有する他の言語に対しても有効である。
【００２５】
図１に示すように、コンピュータ１０１は、各処理を実行するプロセッサ１０２と、メモリ１０３とを備えている。
Ｊａｖａ仮想マシン１０５は、外部ヒープメモリ生成情報取得部１０６、外部ヒープメモリ生成部１０７、不要データ判定部１０８、外部ヒープメモリ解放判定部１０９、外部ヒープメモリ解放部１１０を備えている。
【００２６】
メモリ１０３には、プロセッサ１０２上で実行されるＪａｖａ仮想マシン１０５が実行するＪａｖａプログラム１０４が格納され、Ｊａｖａ仮想マシン１０５が用いるＧＣ対象メモリ領域であるＪａｖａヒープメモリ１１１、ＧＣ対象外メモリである外部ヒープメモリ１１２（１１２−１，２，３）が確保（生成）される。
【００２７】
外部ヒープメモリ１１２は、Ｊａｖａプログラム１０４上に記述された外部ヒープメモリ生成文、もしくはＪａｖａ仮想マシン１０５に含まれる外部ヒープメモリ生成情報取得部１０６で取得した情報を元に生成した外部ヒープメモリ生成バイトコードを実行した回数分だけ生成される。なお、Ｊａｖａプログラム１０４はメモリ１０３上ではなく、コンピュータ１０１に接続された外部記憶装置１１３に記録されていてもよい。Ｊａｖａプログラム１０４には、通常の処理（本発明の特徴以外の処理）のみが記述されているか、外部ヒープメモリ１１２の生成と外部ヒープメモリ１１２へのデータの関連付けの記述が加えられている。通常の処理記述のみである場合は、外部ヒープメモリ生成情報取得部１０６において、外部ヒープメモリ生成箇所及び関連付けるデータの情報を取得する。以後、外部ヒープメモリ１１２に関連付けたデータを「参照関係上の起点データ」もしくは単に「起点データ」と記述する。
【００２８】
Ｊａｖａプログラム１０４を実行するため 、Ｊａｖａプログラム１０４をコンパイルして生成されたバイトコードを読み込んだＪａｖａ仮想マシン１０５は、外部ヒープメモリ生成情報取得部１０６によって外部ヒープ生成情報を読み込み、外部ヒープメモリを生成するバイトコードが実行された際には外部ヒープメモリ生成部１０７によって外部ヒープメモリ１１２を生成する。Ｊａｖａ仮想マシン１０５は、外部ヒープメモリ１１２に関連付けた参照関係上の起点データから参照可能となるデータを、外部ヒープメモリ１１２に直接生成するか、ＧＣ対象メモリであるＪａｖａヒープメモリ１１１に生成した後、数回のＧＣを経ても参照関係が保たれている場合は外部ヒープメモリ１１２に移動させることによって、外部ヒープメモリ１１２にデータを配置する。
【００２９】
Ｊａｖａプログラム１０４の実行中、Ｊａｖａ仮想マシン１０５は不要データ判定部１０８によって、ＧＣ対象メモリであるＪａｖａヒープメモリ１１１における不要データを他データへの参照を持たない別データに変換する。さらに、Ｊａｖａ仮想マシン１０５は、外部ヒープメモリ解放判定部１０９を実行し、外部ヒープメモリ１１２に関して、外部ヒープメモリ１１２内の全データもしくは外部ヒープメモリ１１２に関連付けた起点データへの参照が無い場合は、その外部ヒープメモリ１１２を解放可能と判定し、外部ヒープメモリ解放部１１０によって解放する。その際、Ｊａｖａヒープメモリ１１１（解放対象外メモリ）から外部ヒープメモリ１１２（解放対象メモリ）への参照がある場合は、直接及び間接的に参照可能なデータ群をＪａｖａヒープメモリ１１１（解放対象外メモリ）に移動させることによって、後の実行結果に影響が出ないようにする。
【００３０】
図２に示すサンプルプログラム２０１を参照して、外部ヒープメモリ生成情報取得部１０６について説明する。サンプルプログラム２０１にはｔｅｓｔパッケージに属するＳａｍｐｌｅクラス２０２が記述されており、クラス内にｆｏｏメソッド２０３が記述されている。ｆｏｏメソッド２０３内では、行２０４で示す文においてＨａｓｈＭａｐクラスのデータを生成し、ａｔｔｒｉｂｕｔｅｓフィールド２０５から参照させる処理が行われる。
【００３１】
ここでは、このＨａｓｈＭａｐのデータを外部ヒープメモリ１１２に関連付けて起点データとしたいとする。その方法として、起点データとしたいデータのクラス名と、そのデータを生成するメソッド名を、Ｊａｖａ仮想マシン１０５が読み込み可能な場所、例えば別のファイルに図３の符号３０１の箇所に示すような形で記述しておき、これをＪａｖａ仮想マシン１０５の実行時に読み込ませる。本ファイルには、外部ヒープメモリ１１２に関する起点データのクラス名、当該データを生成するメソッド名の順で、括弧の内部に「，」で区切って記述する。サンプルプログラム２０１を例とすると、起点データのクラスｊａｖａ．ｕｔｉｌ．ＨａｓｈＭａｐを符号３０２の箇所に示すように記述し、本データを生成するｔｅｓｔパッケージに属するＳａｍｐｌｅクラス内のｆｏｏメソッドを符号３０３の箇所に示すように記述する。
【００３２】
この記述を読み込んだＪａｖａ仮想マシン１０５は、行２０４で示す処理文を実行する際、外部ヒープメモリ１１２を１つ生成するとともにＨａｓｈＭａｐデータも生成し、生成した外部ヒープメモリ１１２に生成したＨａｓｈＭａｐデータが関連付けられていると認識する。なお、この記述はＪａｖａ仮想マシン１０５の起動オプション（以下、単に「オプション」ともいう。）としてもよく、図４にその例を示す。
【００３３】
図４は、Ｊａｖａ仮想マシン１０５でＳａｍｐｌｅクラスにあるｍａｉｎメソッドを動作させるための記述に対する、外部ヒープメモリ生成情報指示オプション−ｅｈｅａｐ＿ｃｒｅａｔｅ（符号４０１）として、起点データのクラス名を符号４０２の箇所に示すように、そのデータを生成するメソッド名を符号４０３の箇所に示すように記述した例である。起点データ及び当該データの生成メソッド名はサンプルプログラム２０１を例としている。
【００３４】
ここで、図３、図４に示す起点データと当該データを生成するメソッドの情報をＪａｖａ仮想マシン１０５に読み込む外部ヒープメモリ生成情報取得部１０６の処理を図５に示す。なお、処理５０１〜５０９はＪａｖａ仮想マシン１０５の起動直後であり、まだＪａｖａ仮想マシンの通常の処理（処理５１０）は開始されていないとする。
【００３５】
まず、処理５０１で、図３に示すような外部ヒープメモリ生成情報を記述したファイルがあるか否かを調べる。ある場合（処理５０１でＹｅｓ）は、処理５０２で、まず１行読み、処理５０３でフォーマットを確認してエラーがあるか否かを判定する。エラーがなければ（処理５０３でＮｏ）、処理５０４で、括弧内の最初の「，」までの情報を起点データ（のクラス名）として登録し、処理５０５で、「，」の後の情報を起点データの生成メソッドとして登録する。
【００３６】
その後、処理５０６で、未処理のデータ（行）があるか否かを判定し、ある場合（Ｙｅｓ）は処理５０２に戻り、ない場合（Ｎｏ）は処理５０８に進む。
処理５０３でエラーがあった場合（Ｙｅｓ）は、処理５０７でエラー処理を行い、ファイルの読み込みなしで処理５０８に進む。
【００３７】
処理５０８で、図４に示すような外部ヒープメモリ生成情報を記述したオプションが指定されているかどうかを調べ、ある場合（Ｙｅｓ）は処理５０９で記述されている情報を起点データのクラス名と当該データを生成するメソッド名の情報として登録する。処理５０８でＮｏの後、あるいは、処理５０９の後、処理５１０で、通常のＪａｖａ仮想マシン１０５の処理を開始する。
【００３８】
次に、外部ヒープメモリ解放判定部１０９について説明する。図６に示すように、まず、処理６０１で、全ての利用可能メモリ、すなわち、Ｊａｖａヒープメモリ１１１と外部ヒープメモリ１１２内データからの参照先がどの領域なのかを調べる。処理６０２で、外部ヒープメモリ１１２を１つ選択し、処理６０３で、処理６０１で調べた結果から、選択した外部ヒープメモリ１１２内のデータへの参照が１つでもあるかを調べる。
【００３９】
ない場合（処理６０３でＮｏ）は処理６０５に進み、選択している外部ヒープメモリ１１２を解放可能扱いとする。ある場合（処理６０３でＹｅｓ）は処理６０４に進み、選択している外部ヒープメモリ１１２に関連付けた起点データへの参照があるか否かを調べ、無ければ（Ｎｏ）処理６０５に進み、選択している外部ヒープメモリ１１２を解放可能扱いとする。ある場合（処理６０４でＮｏ）は処理６０６で未処理の外部ヒープメモリ１１２があるか否かを調べ、ある場合（Ｙｅｓ）は処理６０２に戻り、一連の処理を繰り返す。全ての外部ヒープメモリ１１２に対する判定処理が終了した時点（処理６０６でＮｏ）で、処理を終了する。
【００４０】
なお、図６の処理の実行契機は、例えば、ＧＣや、外部ヒープメモリ１１２のサイズの合計値が所定の閾値を超えた場合、あるいは、メモリ１０３の利用可能領域に対する使用割合が所定の閾値を超えた場合とすればよい。図７を用いて、図６の処理を実施した場合のメモリ１０３におけるデータの配置例について説明する。図７に示すメモリイメージでは、ＧＣ対象メモリ領域であるＪａｖａヒープメモリ１１１に加えて、２つの外部ヒープメモリ１１２−１，１１２−２が既に確保されている。また、Ｊａｖａヒープメモリ１１１内にはデータＡ，Ｂ，Ｃ（符号７０１，７０２，７０３）が配置されている。外部ヒープメモリ１１２−１には、データＲ１，１，２，３（符号７０４，７０６，７０５，７１４）、外部ヒープメモリ１１２−２には、データＲ２，４（符号７０７，７０８）が配置されているものとする。
【００４１】
外部ヒープメモリ１１２−１に関連付けた参照関係上の起点データはデータＲ１（符号７０４）であり、外部ヒープメモリ１１２−２に関する起点データはデータＲ２（符号７０７）である。なお、矢印７０９〜７１３はデータ間の参照関係を表す。このような状況下で、まず、処理６０１で全メモリ内のデータの参照先を調べる。その結果、図７における矢印７０９〜７１３で示すような参照関係が把握できる。
【００４２】
次に、処理６０２で外部ヒープメモリを１つ選択するが、ここでは外部ヒープメモリ１１２−１を選択したとする。処理６０３で、外部ヒープメモリ１１２−１の外部データから外部ヒープメモリ１１２−１の内部データへの参照有無を調べると、矢印７１０に示すデータＡ（符号７０１）からデータＲ１（符号７０４）への参照が検出されるので（Ｙｅｓ）、処理６０４に進む。
【００４３】
処理６０４で、領域外からの起点データＲ１への参照を調べるが、先に述べた矢印７１０がこれに該当するため、処理６０６でＹｅｓ→処理６０２と進んで、次の外部ヒープメモリ１１２−２を選択する。再び、処理６０３を実行すると、外部ヒープメモリ１１２−２内のデータＲ２（符号７０７）とデータ４（符号７０８）には、外部からの参照が存在しないため（Ｎｏ）、処理６０５に進み、外部ヒープメモリ１１２−２は解放可能扱いとする。これら一連の処理により、２つの外部ヒープメモリ１１２−１，２のうち、外部ヒープメモリ１１２−２が解放可能扱いとなる。
【００４４】
なお、処理の重さを軽減するため、処理６０３と処理６０４はどちらか一方だけとしてもよい。参照の有無に関する調査である処理６０３と処理６０４のうち、処理６０４における「起点データへの参照の有無の調査」によって、解放可能と見なす外部ヒープメモリ１１２を多くするためには、起点データ、例えば、図７におけるデータＲ１（符号７０４）とデータＲ２（符号７０７）のようなデータへの参照を少なくすることが求められる。しかし、これらの起点データを参照するデータ、例えば図７におけるデータＡからの参照の必要性を判定するためには、データＡが今後の実行で必要であるか否かの判定が必要である。
【００４５】
もし、データＡがＧＣ対象メモリ領域、例えばＪａｖａヒープメモリ１１１に存在し、長時間のＪａｖａプログラムの停止によるＧＣによってのみデータの必要性を判定できる領域に配置されている場合、外部ヒープメモリ１１２の利用によって長時間停止を要するＧＣが非常に発生しにくい状況にあるため、データＡの必要性の判定が長期間行われないことが予想される。一般的なＪａｖａ仮想マシンで採用されている世代別ＧＣ手法においては、Ｊａｖａヒープメモリ１１１をＮｅｗ領域とＯｌｄ領域に分割してＧＣ時間の軽減を図っているが、２領域のうちのＯｌｄ領域は先に述べた長時間停止を要するＧＣを発生させなければデータの必要性の判定ができない領域である。
【００４６】
このような問題を解決するための方法、すなわちＯｌｄ領域のような長時間停止を要するＧＣを発生させなければデータの必要性を判定することができない領域を複数の領域に分割し、分割した領域ごとにその内部データの必要性を判定する不要データ判定部１０８について説明する。図８に示すように、まず、処理８０１で、ＧＣ対象領域（Ｊａｖａヒープメモリ１１１）を複数の領域に分割する。分割サイズはＪａｖａ仮想マシン１０５のオプションや外部入力ファイルで指定するものとする。
【００４７】
処理８０２で、分割した領域を１つ選択し、その領域内のデータに対して、処理８０３〜８０７に示すデータの必要性判定処理を行う。処理８０３で、選択している領域外のデータから領域内のデータへの参照を調べ、参照可能な領域内データに印をつける。次に、処理８０４で、領域内で印がついたデータから参照可能な領域内の印がついていないデータに印をつける処理を行う。これらの処理８０３と処理８０４を実行することで、選択した領域以外のデータから直接もしくは間接的に参照可能な領域内データに印がつけられる。処理８０５では、選択領域内データのうち、無印のデータの情報を収集する。
【００４８】
処理８０６で、無印のデータがあるか否かを判定し、ある場合（Ｙｅｓ）は処理８０７で無印のデータを他データへの参照を持たない別データに変換する。処理８０５で抽出された無印のデータは、他のどのデータからも参照できないデータであり、少なくとも後の実行には必要のないデータであることが確定するため、処理８０７で別データに変換しても問題ない。処理８０６でＮｏの後、あるいは、処理８０７の後、処理８０７１で当該判定を終了する。
【００４９】
次に、処理８０８で、未処理の領域があるか否かを調べ、ある場合（Ｙｅｓ）は処理８０２に戻り、無い場合（Ｎｏ）は、ＧＣ対象領域に対するデータの必要性判定処理（図８の処理）を終了する。図８の処理によって、データ間の不必要な参照を除去することができ、結果として外部ヒープメモリ１１２に関連付けた起点データへの参照が除去されることが期待できる。なお、処理８０７では、不要と判定できたデータを、参照を持たない別データに変換すると述べたが、データ自体は変換せずに、他データへの参照を持つ場所に、どのデータも参照していないことを示すデータを代入する方法や、参照自体に不要な参照であるという属性を持たせ、使用時にその情報を利用するという方法を用いてもよい。
【００５０】
また、図８の処理はいつ実行しても構わないが、ＧＣ終了時やメモリ使用量に関する閾値を実際の使用量が超えた場合に実施するといったケースが実用的であると考えられる。閾値としては、外部ヒープメモリ１１２のサイズの合計値や、メモリ１０３の利用可能領域に対する使用割合などが考えられる。
【００５１】
図９を用いて、図８の処理を実施した場合のメモリ１０３におけるデータの配置例について説明する。図９に示すように、Ｊａｖａヒープメモリ１１１と外部ヒープメモリ１１２があり、符号９０１〜９０７はデータ、矢印９０８〜９１１はデータ間の参照関係を表す。なお、データＢ（符号９０２）は、他領域のデータである他データ９１３（例えばメモリ１０３上のスタックフレームやレジスタなどのＧＣルートと呼ばれる部分や他の外部ヒープメモリ１１２）からの参照（矢印９１４）があると仮定する。
【００５２】
まず、処理８０１に従い、ＧＣ対象領域であるＪａｖａヒープメモリ１１１を分割する。ここでは、Ｊａｖａヒープメモリ１１１を３領域に分割する。図９では、符号９１２−１を領域１、符号９１２−２を領域２、符号９１２−３を領域３としている。
次に、処理８０２に従い、分割した領域を１つ選択するが、ここでは領域１（符号９１２−１）を選択したとする。処理８０３に進み、領域１内のデータＡに対する領域１以外の領域のデータからの参照を調べる。結果として、データＡは他領域のデータから全く参照されていないため、他データから参照されていることを示す印は付加されない。よって、処理８０４は実行されず、処理８０５、８０６に進み、データＡには印がついていないので処理８０７に進む。この時点で、データＡはどのデータからも参照されていないため、データＡを他データへの参照、すなわちデータＲ３（符号９０４）への参照のない別データに置き換える。これで領域１の処理は終了し、領域２（符号９１２−２）と領域３（符号９１２−３）に対して、同様の処理を行う。
【００５３】
領域２にはデータが存在しないため、領域３の処理を行うと、処理８０３でデータＢに印が付加され、処理８０４でデータＣに印が付加される。処理８０５では、領域３内のデータＢとＣの双方とも印がついているため、無印のデータはないということになり、処理を終了する。この時点でのデータ配置のイメージを図１０に示す。データＡ（図９における符号９０１）がデータＡ’（符号１００１）となり、図９における矢印９０９の参照がなくなっていることがわかる。もし、図９の時点で外部ヒープメモリ解放判定部１０９の処理（図６の処理）を実行しても、データＡ（符号９０１）からデータＲ３（符号９０４）への参照（矢印９０９）が存在するため（処理６０３，６０４のいずれもＹｅｓ）、外部ヒープメモリ１１２を解放することはできない。しかし、図１０の状態で、外部ヒープメモリ解放判定部１０９の処理（図６の処理）を実行すると、起点データＲ３への参照がないため（処理６０３，６０４の少なくともいずれかでＮｏ→処理６０５）、外部ヒープメモリ１１２を解放可能と判定することができる。
【００５４】
図８の処理方法では、分割したＧＣ対象領域全てが処理対象となる。しかし、図８に示す不要データ判定部１０８の処理は図６に示す外部ヒープメモリ解放判定部１０９のアルゴリズムを効果的に適用するための処理であり、各外部ヒープメモリ１１２に関連付けた起点データ（例えば、図７のデータＲ１（符号７０４）やデータＲ２（符号７０７）、図９のデータＲ３（符号９０４））を参照するデータ（すなわち、図７のデータＡ（符号７０１）や図９のデータＡ（符号９０１））が配置されている箇所の不要データ判定を行えばよい。
【００５５】
このデータＡ（符号７０１）やデータＡ（符号９０１）が配置されている箇所の情報は、図３〜５に示した外部ヒープメモリ１１２に関連付けるオブジェクトの生成時に得ることができる。図３を例にすると、起点データは符号３０２の箇所に示すようにＨａｓｈＭａｐクラスのデータであり、本データが生成されるのは、符号３０３の箇所に示すようにＳａｍｐｌｅクラスのｔｅｓｔメソッドであるが、その際にこのＳａｍｐｌｅクラスのデータ配置を覚えておき、図８に示す不要データ判定部１０８の処理時に利用すればよい。
【００５６】
図１１にそのアルゴリズムのフローチャートを示す。図８のフローチャートとの違いは、処理８０２における分割された領域の１つの選択を、処理１１０１に示すように起点データを参照するデータが存在する領域の選択とした点である。これに伴い、処理８０８も、処理１１０２に示すように起点データへの参照を持つ領域で未処理の領域があるか否かを判定するようにしている。これらについて、図１２を用いて説明する。
【００５７】
図１２では、図９と比較して、Ｊａｖａヒープメモリ１１１内のデータ配置が異なっている。領域３（符号９１２−３）にデータＡ（符号１２０１）があり、そのデータＡからデータＲ３（符号９０４）への参照（矢印１２０５）が存在する。また、データＢ（符号１２０２）、データＣ（符号１２０３）が領域１（符号９１２−１）に、データＤ（符号１２０４）が領域２（符号９１２−２）にあるものとする。
【００５８】
データＲ３（符号９０４）の生成時に、これを参照（矢印１２０５）するデータＡ（符号１２０１）の配置情報をＪａｖａ仮想マシン１０５が保持しているものとして、図１１のフローチャートの処理を適用する。処理１１０１で、領域１〜３中の起点データ（Ｒ３（符号９０４））への参照を持つデータがある場所は領域３（符号９１２−３）のみであるため、領域３を選択する。処理８０３〜８０７１を実行すると、データＡへの参照は存在しないため、データＡ（符号１２０１）を、データＡからデータＲ３への参照（矢印１２０５）が無い別データに変換することができる。そして、処理１１０２で、起点データ（Ｒ３（符号９０４））への参照を持つデータが存在する領域はない（Ｎｏ）と判定でき、処理を終了する。
【００５９】
この状態で図６に示す外部ヒープメモリ解放判定部１０９のフローチャートの処理を適用すると、外部ヒープメモリ１１２は解放可能と判定（処理６０３，６０４の少なくともいずれかでＮｏ→処理６０５）することができる。もし、図８に示すフローチャートの処理を適用した場合、領域１，２に存在するデータＢ〜Ｄへの参照も調べることになるが、図１１のフローチャートの処理を適用するとこのような領域を調べなくてよく、効率がよい。
【００６０】
図８に示す処理８０３〜８０７１では、ガベージコレクション対象メモリを分割した小領域において、ある領域内のデータと、それと異なる領域内のデータとが相互参照状態にある場合、それらのデータの必要性の判定を行っても、不必要とは判定されない。例えば図１４にように、ガベージコレクション対象であるＪａｖａヒープメモリ１１１を符号９１２−１〜９１２−３に示すように３分割した領域にデータＡ（符号１４０１）とデータＢ（符号１４０２）があり、それぞれ領域１と領域３に配置されているとする。また、その他のデータ（符号１４０３〜１４０５）と参照（矢印１４０７，１４０８）については、図示の通りである。
【００６１】
この状態に対して、図８に示すフローチャートの処理を適用した場合、まず、領域１内データに対する参照を調べると、領域３のデータＢからデータＡへの参照（矢印１４０９）が検出されるため、データＡは後の実行で必要であると判定される（処理８０３で印がつけられる）。次に、領域３内データに対する参照を調べると、領域１のデータＡからデータＢへの参照（矢印１４１０）が検出されるため、データＢも後の実行で必要と判定される（処理８０３で印がつけられる）。
【００６２】
しかし、データＡをデータＢと同一の領域に、もしくはデータＢをデータＡと同一の領域に移動させると、データＡとデータＢに対する領域外からの参照は存在しないため、両データを不必要なデータと判定できる（処理８０３で印がつけられない）。結果として、データＡからデータＲ４への参照（矢印１４０６）を除去できるため、外部ヒープメモリ１１２を解放可能と判定できる。このように、相互参照状態にあるデータが異なる領域に存在するとデータの必要性判定の正確性が著しく低下するが、同一領域に存在するようにするとデータの必要性判定がより正確に行えることがわかる。そのアルゴリズムのフローチャートを図１５に示す。
【００６３】
図１５に示すフローチャートは、図８のフローチャートと比較して、処理８０７が処理１５０１に置き換えられている点で異なる。処理８０７は不必要と判定できたデータを他への参照を持たないデータに変換する処理だが、処理１５０１では、処理８０３及び処理８０４で印をつけたデータがメモリ１０３上で連続になるように移動させる処理を行う。その結果として、相互参照状態にあるデータが近くに配置されるようになり、同一領域に配置されやすくなる。図１４の状態に対して図１５に示すフローチャートの処理を適用した後のメモリ１０３のイメージを図１６に示す。
【００６４】
図１６におけるＪａｖａヒープメモリ１１１は、メモリ１０３の空間上、左側が低位アドレス、右側が高位アドレスとし、図１５の処理１５０１では印を付加されたオブジェクトを低位アドレス側に移動させるものとする。図１６においては、データＡとデータＢの間にはデータは存在しないため、データＢが符号１６０１で示すように低位アドレス側に移動し、データＡと同じ領域１内に配置される。この状態で図８の不要データ判定を実行すると、データＡ及びデータＢに対する参照は存在しないため、両データとも参照を持たない別データに変換する（処理８０７を実行する）ことができる。結果として、参照（矢印１４０６）を除去することができ、外部ヒープメモリ解放判定部１０９による処理（図６の処理）を実行すると、この外部ヒープメモリ１１２を解放可能と判定できる。
【００６５】
このように、本実施形態に係るメモリ管理方法によれば、ガベージコレクションによってメモリ１０３の管理を行う場合、外部ヒープメモリ１１２に関連付けたデータへの参照が不要と判定できた場合、その外部ヒープメモリ１１２を解放可能と見なすことによって、ソースプログラムへの修正なしで、外部ヒープメモリ１１２を利用可能にすることができる。その際、外部ヒープメモリ１１２を効率的に解放可能とするため、ガベージコレクション対象のＪａｖａヒープメモリ１１１を複数の領域に分割し、分割した領域ごとにデータの必要性を判定し、後の実行で全く必要ないと判定できたデータからの参照を不要な参照と見なすことで、結果として外部ヒープメモリ１１２への参照を積極的に減少させ、解放可能な外部ヒープメモリ１１２を増加させることができる。
【００６６】
そして、外部ヒープメモリ１１２の解放処理を、オプションや外部入力ファイルで与えられた外部ヒープメモリ１１２の生成及び関連付けるデータの情報を併用して自動化することによって、ソースプログラムへのＡＰＩ記述無しで外部ヒープメモリ１１２が利用可能となるため、プログラム開発期間の短縮や、プログラムミスによる長時間ＧＣの誘発阻止を期待できる。また、外部ヒープメモリ１１２を適用したいアプリケーションのプログラム修正が許されていない場合や、プログラムが存在しない場合においても、ＡＰＩの記述無しに外部ヒープメモリ１１２を利用可能とすることによって、ポータビリティを保持したまま、より多くのプログラムに外部ヒープメモリ１１２を適用することができる。
【００６７】
以上で実施形態の説明を終えるが、本発明の態様はこれらに限定されるものではない。具体的な構成や処理について、本発明の主旨を逸脱しない範囲で適宜変更が可能である。
【符号の説明】
【００６８】
１０１…コンピュータ
１０２…プロセッサ
１０３…メモリ
１０４…Ｊａｖａプログラム
１０５…Ｊａｖａ仮想マシン
１０６…外部ヒープメモリ生成情報取得部
１０７…外部ヒープメモリ生成部
１０８…不要データ判定部
１０９…外部ヒープメモリ解放判定部
１１０…外部ヒープメモリ解放部
１１１…Ｊａｖａヒープメモリ
１１２…外部ヒープメモリ
１１３…外部記憶装置
【図１】
2010225033.tif 000003
【図２】
2010225033.tif 000004
【図３】
2010225033.tif 000005
【図４】
2010225033.tif 000006
【図５】
2010225033.tif 000007
【図６】
2010225033.tif 000008
【図７】
2010225033.tif 000009
【図８】
2010225033.tif 000010
【図９】
2010225033.tif 000011
【図１０】
2010225033.tif 000012
【図１１】
2010225033.tif 000013
【図１２】
2010225033.tif 000014
【図１３】
2010225033.tif 000015
【図１４】
2010225033.tif 000016
【図１５】
2010225033.tif 000017
【図１６】
2010225033.tif 000018
【図１７】
2010225033.tif 000019
【図１８】
2010225033.tif 000020
【図１９】
2010225033.tif 000021
【図２０】
2010225033.tif 000022