(57)【特許請求の範囲】
【請求項１】
文字列処理を行うインタプリタ言語によってオブジェクトのメモリを管理するメモリ管理方法において、
インタプリタで使用される多数の文字から使用頻度の低い文字を選び、該文字の並びで構成した識別記号を含む文字列（ハンドル）によって、インタプリタからメモリ管理の必要なオブジェクトへの参照を表し、
ハンドルに対応したインタプリタ言語上のデータ構造（ハンドル構造体）を定義するとともに、ハンドルへの参照回数をハンドル構造体上のデータとして定義し、
インタプリタ言語の変数が変更されることによってオブジェクトの参照状態が変更される度に、該オブジェクトに対応するハンドル構造体における参照回数を増減し、その参照回数を監視することによってメモリ管理を行う
ことを特徴とするメモリ管理方法。
【請求項２】
オブジェクトを指すポインタをハンドル構造体上のデータとして定義するとともに、ハンドル構造体の配列またはリストを用意し、ハンドルの文字列をキーとしたインデックス及びオブジェクトを指すポインタ値をキーとしたインデックスを用意することを特徴とする請求項１記載のメモリ管理方法。
【発明の詳細な説明】
【０００１】
【発明の属する技術分野】
本発明は、インタプリタ言語によるプログラムの製作作業時のメモリ管理方法に関するものである。
【０００２】
【従来の技術】
文字列処埋を行うインタプリタ言語では、あらゆるデータを文字列で表している。このような言語でオブジェクトを取り扱う場合、オブジェクトへの参照を何らかの文字列（以下、ハンドルと称す。）で表す。通常、オブジェクト参照に当ってはメモリの割り当て、解放が必要である。こうしたメモリ管理の必要なプログラムを製作する時、プログラム製作者はオブジェクトが参照されているかどうか、即ちハンドルが再び使用される可能性があるかどうかを常に意識し、参照されなくなった時点でオブジェクトのメモリを開放する操作をプログラムに組み込んでいた。
【０００３】
【発明が解決しようとする課題】
前述したように、メモリ管埋の必要なオブジェクトを用いてプログラムを製作する時、プログラム製作者はオブジェクトが参照されているかどうかを常に正しく意識する必要がある。なぜなら、参照されているオブジェクトのメモリを開放してしまうと、開放されたメモリに対するアクセスが発生し、また、既に参照されなくなったオブジェクトのメモリを開放しないでおくとメモリを浪費し、メモリの不足が発生し、このようなメモリ管理の誤りは深刻なプログラムエラーを引き起こしてしまうからである。
【０００４】
インタプリタ言語では、実行時に変数の内容が監視できるため、オブジェクトが参照されているかどうかをプログラム製作者に代わってプログラムを解釈実行するインタプリタが監視することができる。しかしながら、文字列処理を行うこれまでのインタプリタ言語では、文字列の中に埋め込まれたオブジェクトを指し示す部分（ハンドル）についてまでは監視しないため、ハンドルによるオブジェクトのメモリ管埋はプログラム製作者が行うことになり、プログラム製作の作業効率が悪いという問題があった。
【０００５】
本発明の目的は、主として文字列処埋を行うインタプリタ言語においても、プログラム製作者によるメモリ管理を必要としないメモリ管理方法を提供することにある。
【０００６】
【課題を解決するための手段】
前記課題を解決するため、本発明では、インタプリタで使用される多数の文字から使用頻度の低い文字を選び、該文字の並びで構成した識別記号を含む文字列（ハンドル）によって、インタプリタからメモリ管理の必要なオブジェクトへの参照を表し、ハンドルに対応したインタプリタ言語上のデータ構造（ハンドル構造体）を定義するとともに、ハンドルへの参照回数をハンドル構造体上のデータとして定義し、インタプリタ言語の変数が変更されることによってオブジェクトの参照状態が変更される度に、該オブジェクトに対応するハンドル構造体における参照回数を増減し、その参照回数を監視することによってメモリ管理を行うことにより、ハンドルによるオブジェクトの参照状況をインタプリタが監視できるようにし、誤りのないメモリの割り当て、解放をインタプリタ側で管理可能とする。
【０００７】
また、オブジェクトを指すポインタをハンドル構造体上のデータとして定義するとともに、ハンドル構造体の配列またはリストを用意し、ハンドルの文字列をキーとしたインデックス及びオブジェクトを指すポインタ値をキーとしたインデックスを用意することにより、高速な処理を可能とする。
【０００８】
【発明の実施の形態】
オブジェクトへの参照を表すハンドルを、通常は現れないような特別な文字の並びで構成した識別記号で始まるようにし、その後ろにハンドル毎に異なる文字列を付けて構成する、例えば”＆＃％＄０００１２３”のような文字列を構成する。ここで”＆＃％＄”は識別記号であり、通常の文章では使用頻度の低い文字、例えば、〜，！，＠，＃，＄，％，＾，＆等から選択した文字を複数並べて、通常の文章で使われる可能性が非常に低い文字列を用いる。また、”０００１２３”はハンドル毎に異なる文字列である。インタプリタは、変数中の文字列から前記識別記号を検索することにより、ハンドルを捜し出すことができる。
【０００９】
オブジェクトのメモリの開放を行う必要があるのは、そのオブジェクトがどこからも参照されなくなった場合である。参照されているかどうかは、実行中のプログラムのデータ領域のどこかにハンドルが存在するかどうかで判断できる。
【００１０】
図１は本発明の実施の形態の一例を示すもので、以下のようなデータ構成を有している。
【００１１】
１．ハンドルを管理するものとして、以下に示すような内容を含む構造体（以下、ハンドル構造体と称す。）を用意する。
・オブジェクトを指すポインタ
・オブジェクトのメモリを開放する必要があるかどうかのフラグ
・ハンドルの参照数
２．ハンドル構造体の配列またはリスト等を用意する。ハンドルの文字列から、この配列またはリスト等の要素が直ちに分かるようにしておく。例えば、ハンドルの文字列をキーとしたインデックスを作り、対応するハンドルリストの要素が直ちに得られるようにする。
【００１２】
３．ハンドル構造体は、オブジェクトを指すポインタ値からできるだけ高速に見つけ出せるようにしておく。例えば、ポインタ値をキーとしたインデックスを用いる。
【００１３】
次に、本発明方法の動作を説明する。
【００１４】
１．ハンドルが必要になった時（インタプリタにおいて、データ処理中にオブジェクト参照のイベントが発生した時）は、オブジェクトを指すポインタをキーにしてハンドル構造体を探す。既にハンドル構造体があれば、その構造体のハンドルを使う。ハンドルがまだ存在しない場合には、新たにハンドル構造体の要素を作るか、使用されていないハンドル構造体を捜し出し、そこに情報を設定する。ハンドルが指すオブジェクトが後でメモリを開放しなければならないものであれば、そのフラグをセットする。ハンドルの参照数は０にする。
【００１５】
２．インタプリタのオブジェクト参照に関わる変数を変更する際に、以下の処理を行う。
【００１６】
・変数に以前に設定されていた文字列を捜査し、ハンドルの識別記号を探す。見つかった各ハンドルは、この変更によって参照がなくなるので、ハンドル構造体の参照数を１減らす。例えば、代入操作によって変数Ａが変数Ｂに置き換えられた場合を考えると、変数Ａに関わるハンドルの参照数を減らすことになる。
【００１７】
・変数に新たに設定する文字列を捜査し、ハンドルの識別記号を探す。見つかった各ハンドルは、この変更によって参照が増えるので、ハンドル構造体の参照数を１増やす。例えば、代入操作によって変数Ａが変数Ｂに置き換えられた場合を考えると、変数Ｂに関わるハンドルの参照数を増やすことになる。
【００１８】
３．オブジェクトのメモリを開放する必要がなくなった場合（例えば、データ処理中に内部でオブジェクトのメモリを開放するサブルーチンにオブジェクトを渡した場合）には、ハンドル構造体のメモリ開放の必要性を示すフラグを寝かす。逆に、再びオブジェクトのメモリを開放する必要が発生した場合（例えば、データ処埋中にオブジェクトのメモリ管理権を譲り受けるサブルーチンを呼出した場合）には、ハンドル構造体のメモリ開放の必要性を示すフラグを立てる。
【００１９】
４．何らかの理由でオブジェクトのメモリが開放されてしまった場合（例えば、データ処理中に内部でオブジェクトのメモリを開放するサブルーチンがオブジェクトのメモリを開放した場合）には、ハンドル構造体の要素も削除する。
【００２０】
５．インタプリタは何らかのタイミングでハンドル構造体の各要素を捜査し、参照数が０になっているハンドル構造体を削除する。この時、オブジェクトのメモリの開放が必要であれば開放する。
【００２１】
図２に本発明方法の動作フローチャートを示す。この図では、上記３、４の処理は省略している。また、５の処理を行うタイミングを変数の変更時として記述している。５の処埋はインタプリタ起動後のいずれの時点で行っても良いが、
（１）２．の処理の終了後、（２）プログラムの待状態にある時、（３）別途定めたハンドル数の上限もしくは割り付けられているメモリの上限になった時、等が有効である。（１）は最も細かく監視する方法であり、（２）はインタプリタに負担をかけない方法、（３）は（１）と（２）の中間であり、監視の必要性を受けて動作する。
【００２２】
ここで、前記識別記号と同じ文字列が、たまたま通常の文字列としてデータの文字列中に含まれる可能性もあるが、対応するハンドル構造体がなければハンドルとして認識しないようにすれば問題ない。これは文字列中の識別記号以外の部分が異なれば、それはハンドル構造体の識別記号でなく、通常のデータ上の文字列として扱うことによって容易に可能である。
【００２３】
また、使用中のハンドルと全く同じ文字列が通常の文字列として使われていると、その文字列が変数中に存在する間、ハンドル構造体の参照数が本来の参照数より多く設定され、本来の参照数が０になってもオブジェクトのメモリが開放されない。しかし、通常の文字列として使われているハンドルと全く同じ文字列が変数からなくなった時点でメモリは開放されるため、実用上問題はない。ハンドルと全く同じ文字列が大量にしかも永久にデータ中に存在する場合に限り、メモリの浪費の問題が発生するが、前述したように、もともとハンドル用の文字列として使用頻度の低い文字を選定しており、ハンドルと全く同じ文字列が大量に続くことは有り得ないと考えて良い。
【００２４】
【実施例】
文字列処理を行うインタプリタ言語としてＴｃｌを使用し、メモリ管埋が必要なオブジェクトとしてＣ＋＋言語のインスタンスを使用した場合についての実施例を示す。
【００２５】
Ｔｃｌはアプリケーション独立の拡張可能なコマンド解釈部ライブラリである。Ｔｃｌの参考文献としては、“Ｔｃｌ  ａｎｄ  ｔｈｅ  Ｔｋ  Ｔｏｏｌｋｉｔ”Ｊｏｈｎ  Ｏ．Ｏｕｓｔｅｒｈｏｕｔ  ，Ａｄｄｉｓｏｎ−Ｗｅｓｌｅｙ，１９９４、がある。
【００２６】
本実施例は、Ｃ＋＋言語で製作されたプログラムに、Ｔｃｌによるアプリケーションプログラムインタフェース（ＡＰＩ）を追加した場合に相当する。このようなＡＰＩには、Ｔｃｌのようなインタプリタ言語の持つ、コンパイルが不用で即実行可能であるという利点と、Ｃ＋＋言語のように高速に動作するコンパイル言語の利点を合わせて用いることができるという特徴がある。
【００２７】
このようなＡＰＩでは、Ｔｃｌにコマンドを追加し、そのコマンドの中でＣ＋＋のプログラムを呼び出す。呼び出されたＣ＋＋のプログラムが何らかのＣ＋＋インスタンスをＴｃｌ側に返す場合、Ｔｃｌではデータが全て文字列であるため、Ｃ＋＋インスタンスからそれを指し示すハンドルを生成し、これを返す。追加したＴｃｌのコマンドに対して、Ｔｃｌ側から以前に得たＣ＋＋インスタンスを渡す場合にはそのハンドルを渡す。コマンドから呼び出されたＣ＋＋プログラムは、ハンドルからＣ＋＋インスタンスへのポインタを得て、Ｃ＋＋インスタンスに対する処理を実施する。
【００２８】
Ｔｃｌでは、データは全て文字列であり、その文字列は変数から参照されている。データを表す全変数から参照されている文字列の中に、あるＣ＋＋のインスタンスを指すハンドルがどこにも存在しなければ、そのＣ＋＋インスタンスは二度と参照されないので、ｄｅｌｅｔｅしてかまわないことになる。なお、ｄｅｌｅｔｅとはＣ＋＋言語におけるメモリ開放指示である。
【００２９】
そこで、Ｔｃｌの変数に文字列を入れる際に、文字列中のハンドルの存在の有無を調べ、ハンドルの存在状態を完全に把握すれば、ＡＰＩ側でメモリ管理を行うことができ、ＡＰＩを使うプログラム製作者はメモリ管埋をしなくて済む。
【００３０】
以下に、その方法の具体的な手順の例を示す。
【００３１】
１．ハンドルを管理するものとして、以下に示すような内容を含む構造体（以下、ハンドル構造体と称す。）を用意する。
・Ｃ＋＋のインスタンスを指すポインタ
・Ｃ＋＋のインスタンスのクラス
・Ｃ＋＋のインスタンスをｄｅｌｅｔｅする必要があるかどうかのフラグ
・ハンドルの参照数
・ハンドル構造体が使われているかどうかのフラグ
２．十分な大きさのハンドル構造体の配列を用意する。ハンドルの名前はこの配列の要素番号から作るようにする。逆に言えば、ハンドルの名前から、ハンドル構造体の配列の要素番号が分かるようにしておく。例えば、ハンドルが”＆＃％＄０００００３”なら、このハンドルに対応するハンドル構造体は”ｘｘｘｘ［３］”で得られるようにする。
【００３２】
３．ハンドル構造体の各要素は、Ｃ＋＋のインスタンスを指すポインタをキーにしたハッシュテーブルを製作してこれに登録しておく。つまり、ポインタ値からできるだけ高速にハンドル構造体を見つけ出せるようにしておく。ハッシュテーブルとは、ある大きさのテーブルを用意し、各要素をこのテーブル内にできるだけ均等に振り分けるため、キーをハッシュ関数によりテーブルの大きさの範囲の数値に変換し、テーブル中のこの数値の位置に要素を格納するものである。検索時にはキーをハッシュ関数により数値に変換し、テーブル中のこの数値の位置から要素を探すことにより、高速に検索できる。
【００３３】
４．ＡＰＩとしてＴｃｌに追加されたコマンドからハンドルを返す場合等、ハンドルが必要になった時は、Ｃ＋＋のインスタンスを指すポインタをキーにしてハッシュテーブルからハンドル構造体の要素を探す。既にハンドル構造体の要素があれば、その要素の配列の要素番号からハンドル名を作って返す。ハンドルがまだ存在しない場合には、使用されていないハンドル構造体の要素を捜し出し、そこに情報を設定する。ハンドルが指すＣ＋＋のインスタンスが、後でｄｅｌｅｔｅしなければならないものであれば、そのフラグをセットする。ハンドルの参照数は０にする。
【００３４】
５．Ｔｃｌにおいて、変数への代入を実施している部分を以下のように改造する。
【００３５】
・変数に以前に設定されていた文字列を捜査して、この文字列から参照されていた各ハンドルを探す。各ハンドルは、この代入によって参照がなくなるので、ハンドルの参照数を１減らす。
【００３６】
・変数に新たに代入される文字列を捜査して、この文字列から参照されている各ハンドルを探す。各ハンドルは、この代入によって参照が増えるので、ハンドルの参照数を１増やす。
【００３７】
・代入終了後、この代入によって参照数が変化したハンドルの中で参照数が０になったものがあれば、そのハンドルのハンドル構造体を未使用に設定し、ハッシュテーブルから除き、Ｃ＋＋インスタンスのｄｅｌｅｔｅが必要であればｄｅｌｅｔｅを実施する。
【００３８】
６．Ｔｃｌにおいて、変数を無効にしている部分（例えば、ｒｅｔｕｒｎによりプロシージャのローカル変数を破棄している部分）を改造して、参照されなくなるハンドルの参照数を減らす処埋をいれる。変数の無効化よって参照数が０になったハンドルがあれば、そのハンドルのハンドル構造体を未使用に設定し、ハッシュテーブルから除き、Ｃ＋＋インスタンスのｄｅｌｅｔｅが必要であればｄｅｌｅｔｅを実施する。
【００３９】
７．ハンドルがＡＰＩとしてＴｃｌに追加されたコマンドを通じてＣ＋＋インスタンスへのポインタに戻され、Ｃ＋＋の関数に渡され、その関数内でメモリ管理がＣ＋＋プログラム側に移った場合には、ハンドル構造体のｄｅｌｅｔｅの必要性のフラグを寝かす。
【００４０】
８．Ｃ＋＋インスタンスのデストラクタを改造し、Ｃ＋＋インスタンスがＣ＋＋プログラム側でｄｅｌｅｔｅされた場合には、そのＣ＋＋インスタンスを指すハンドル構造体を探してＣ＋＋インスタンスへのポインタをＮＵＬＬに設定する。同時に、ハンドル構造体をＣ＋＋インスタンスへのポインタをキーとしたハッシュテーブルから除く。
【００４１】
未使用のハンドル構造体、参照数が０のハンドル構造体をそれぞれ専用のリストに繋いで管理することにより、さらに高速に処理を行うことができる。
【００４２】
【発明の効果】
以上説明したように、本発明によれば、文字列処理を行うインタプリタ言語においても、メモリ管理を行うことなく、効率的なプログラム製作を行うことができるとともに、メモリ管理の誤りによる深刻なプログラムエラーを完全に排除することができる。
【図面の簡単な説明】
【図１】本発明の実施の形態の一例を示すデータ構成図
【図２】本発明方法の動作フローチャート
【図１】
0003582756.tif 000002
【図２】
0003582756.tif 000003