ガーベジコレクション | Programming Place Plus 用語集

トップページ用語集

名称

解説

プログラム実行中に確保されたメモリ領域のうち、使用されなくなったものを判断して、自動的に解放をおこなう機能のことです。

「ガーベジ (garbage)」とは「ゴミ」のことです。ここでは、メモリ上に確保されたが、用を終えて不要になった領域のことを指しています。

ガーベジコレクションは、ダイナミックメモリアロケーションによって確保されたメモリ領域の解放を自動的におこなう機能です。プログラムの実行中、何らかのタイミングで一時的に処理の進行を止め(そうでないとガーベジコレクションの作業中にメモリの状況が変化する恐れがあるから)、確保されているメモリ領域がまだ使用中であるかどうかを判定し、使用中でないことが明確であるものが発見されたら、そのメモリ領域を解放します。

ガーベジコレクションをおこなうプログラムのことをガーベジコレクタと呼びます。ガーベジコレクタは、処理系フレームワークライブラリなどで提供され、プログラミング言語によっては言語仕様となっています。C言語や C++ では、仕様上はガーベジコレクションに関する規定はなく(どちらでも良い)、一般的には行いませんが、ライブラリによって提供されるものもあります(Boehm GC など)。C# などの .NET系の言語や、Java などではガーベジコレクションが行われるほか、Ruby などの動的言語にも存在することが多いです。

ガーベジコレクションが行われる環境では、プログラマーソースコード上に解放の処理を記述しませんが、使わなくなったメモリ領域が分かるようにする必要はあります。たとえば、確保された領域を指すポインタリファレンスがいなくなれば、その領域は使われなくなったと判断できます。次の架空のプログラミング言語のソースコードでは、実行中に確保された領域を指すポインタ変数にヌルポインタが代入されたことで、メモリ領域が使用されなくなったことが明確になります。

int* p = NULL;

void f()
{
    p = alloc(sizeof(int));  // 動的にメモリ領域を確保し、その領域を指すポインタを得る
                             // p がある限り、p を経由してメモリ領域をアクセスできるので、
                             // その間は、ガーベジコレクションは解放作業を行えない。

    // ...

    p = NULL;  // p が NULL で上書きされたことにより、メモリ領域をアクセスする方法がなくなった(はず)。
               // この時点で、メモリ領域は不要になったことが分かり、これ以降、ガーベジコレクションは解放を行える。
}

一方で、次のようなコードでは、まだ使用が続いていると考えられるため、解放することができません。

int* f()
{
    int* p = alloc(sizeof(int));  // 動的にメモリ領域を確保し、その領域を指すポインタを得る
                                  // p がある限り、p を経由してメモリ領域をアクセスできるので、
                                  // その間は、ガーベジコレクションは解放作業を行えない。

    // ...

    return p;  // ローカル変数である p は消えるものの、p のコピーが呼び出し元に返されるため、
               // p が指しているメモリ領域が使用され続けるのかどうか、ここでは判断できない。
}

関数f の呼び出し元が、戻り値を受け取るなら、確保されたメモリ領域の使用は続くでしょうし、受け取らないなら使用は続かないことになります。

void g()
{
    int* p = f();  // f() の中で確保されたメモリ領域は使用され続ける
    f();           // f() の中で確保されたメモリ領域は使用されない(解放できる)
}

ガーベジコレクションが行われる環境では、ソースコード上から、解放に関するコードがなくなるため、メモリリークや、同じメモリ領域に対する二重解放ダングリングポインタの発生といった、ダイナミックメモリアロケーションに付きまとうバグを、完全ではないにせよ、防止する効果があります。先ほどのプログラム例のように、ヌルポインタを代入するなどして、使用しなくなったことを明確に示さなければならない状況では、それをプログラマーがそれを忘れてしまう可能性は残ります。

ガーベジコレクションの実行タイミングは、基本的にガーベジコレクタに任せることになります。ガーベジコレクションが実行されるとき、プログラムの実行が一時的に止められるため、アプリケーションの内容によっては問題になる可能性があります(たとえばゲームでは、一瞬、映像が固まり、プレイヤーの入力が効かないなどの問題が起こる可能性がある)。ガーベジコレクションを実現する方法は長年研究されており、このような問題は完全ではないにせよ、改善はされています(世代別ガーベジコレクションなど)。


メモリ上のデータの配置を整理して、未使用領域が1つの連続的な領域になるようにするメモリコンパクションと混同されることがあります。実際、ガベージコレクションとともにメモリコンパクションも行われることがありますが、機能としては別のものです。ガーベジコレクションは不要になった領域を自動的に解放することで、メモリリークなどのバグを防ぐ意味があるのに対し、メモリコンパクションはメモリを整理してフラグメンテーションを防ぐ意味があります。


参考リンク

更新履歴


用語集のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
X で ポストフォロー LINE で送る noteで書く
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー
先頭へ戻る