ガベージコレクション(GarbageCollection)とは、動的に確保されたメモリ領域のうち、使われなくなった領域(garbage:ゴミ)を自動的に収集(collection)して解放する機能。ガベージコレクションを行うモジュール(実装)の事をガベージコレクタ(GarbageCollecter,GC)と言う。
ガベージコレクションは言語や標準ライブラリ、OSといった環境に組み込まれて提供される。
プログラムが動作するとき、プログラムが使うデータを格納するためにメモリ領域を確保するが、プログラミングの時点でサイズが決まっていないデータ、実行中にサイズが変化するデータについては、メモリを動的に確保してデータを格納する。この動的に確保されたメモリ領域は、使用が終われば動的に解放を行わなければならない。
というミスを発生させることになる。メモリの確保・解放を人力で管理するのは大変で面倒なので、コンピュータにさせよう!という話になる。プログラマは面倒ごとをコンピュータに任せたがる人種なのだ。
なお、メモリの確保と解放を行うことで必然的に発生しうるメモリフラグメンテーションを解消すべく、メモリの連続未使用領域の確保を行うことをガベージコレクションと呼ぶことがあるが、厳密にはこれはメモリコンパクションと呼び、正確とは言いがたい。ガベージコレクションの実装としてメモリコンパクションの機能が内包されているケースが多く、同一の意味合いで用いられることがあるので注意と理解が必要である。
この動的に解放を行うという事を、プログラマが意識しなくてよいように、言語や標準ライブラリに組み込まれたのがガベージコレクションと呼ばれる機能である。これによってプログラマは、メモリの解放を意識せずにたくさんのメモリをより自由に使えるようになった。また、プログラミングの敷居を下げた。
また、個々のプログラマが独自にメモリ管理を行う代わりに、ガベージコレクションを環境とセットにして実装し他のプログラマに提供することで、より洗練された高速なガベージコレクション機能の恩恵を多くのプログラマが受けることにもなる。すげぇ人が作ったすげぇガベージコレクタを、みんなで使った方が効率いいよね?ということ。
無論、標準ではGCが存在しないC言語もライブラリを使えば利用可能である。
ただし、欠点もある。ガベージコレクタが動くとき、ガベージコレクタ自身がCPUを消費してしまう。アルゴリズムにも寄るが、ガベージコレクタはプログラムが使用しているメモリ全体をチェックするため、非常に負荷がかかる。また、ガベージコレクション処理が完了する時間も一般的なGCでは予測できない。(予測可能なアルゴリズムもあるにはある)
メモリ管理をプログラマが意識せずに済むことの対価として、プログラマはガベージコレクタを細かく制御できない。そのため、予測しないタイミングでCPUに高負荷がかかり、本来のプログラムの実行に処理が回らないといったことが起きる可能性がある。このため、リアルタイム性が要求されるプログラムには不向きと言われる。
ガベージコレクションは手動管理に比べて処理が重いと思われていることが多いが、これは必ずしも正しくない。ガベージコレクション特有のコストがあるのは確かだが、そもそも手動管理を行う場合でもメモリの確保・解法に掛かる実行コスト自体は同じなのだ。例えば、プログラムがアイドル状態の時にGCを行うといった最適化が行われれば全体的な性能は向上する可能性がある。また、別スレッドにおいてメモリの管理を行うことで性能低下を殆ど起こさないようにGCを行える場合もあるだろう。(これらが可能かどうかはプログラムの動作や、メモリがどのように使用されているか、そしてGCの性能に依る)
では何故ガベージコレクションに重い印象が付きまとうかというと、欠点の項にあるように一度動き出すとその時にまとめて負荷が掛かる傾向があるためである。つまりこれはゴミはこまめに捨てたほうが良いのか、普段は貯めておいてたまに大掃除をした方が良いのかということであり、プログラムの性能が途中で変動して問題ないのかどうかにかかってくる。
というわけで「負荷軽減のために手動管理する」というのは正しい理解ではないことを覚えておきたい。時に手動管理する方が有利なのは、あくまでその方が動きを予測できるからなのだ。
各メモリ領域を参照するポインタの数を監視し、これがゼロになった領域を不要な領域として解放していく手法を中心とすることが多いが、プログラムコードが、不要な保存域を参照し続けるようなつくりになっていると、せっかくのガベージコレクションも役に立てない。
例えば、C#によるGUIプログラミングにおいて、Formのメンバ変数が膨大なDictionaryを持ち続けているであるとか、Javaによるサーバサイドプログラミングにおいて、HttpSessionへsetAttributeなどでどんどん値を追加していくとか、そのような実装を行っている場合、たとえその内容が使用されないものであったとしても、ガベージコレクタはこれらの領域が不要であると判断することができず、従来のメモリリークと同様の現象が発生する。
BASICやFortranなどの、古い高級言語には独自のメモリ管理機構があった。これをガベージコレクションと呼ぶかどうかは分からない。
ガベージコレクタが初めて実装されたのは、Lisp言語だといわれている。ただし、当時のコンピュータ性能ではガベージコレクション機能は荷が重く、実用にはならなかった。研究機関や教育機関では利用されていたが、一般への普及にはコンピュータ性能が上昇するのを待たなければならなかった。
90年代後半になるまで、開発言語はC/C++が一般的であり、ガベージコレクションはそもそもない(C)か、あるにはあるがまともに使えなかった(C++のauto_ptr。現在はshared_ptrとweak_ptrなどでそれなりにまともに扱える)。
Java言語が光を浴びると、JavaVMに搭載されたガベージコレクションが有名になった。当時主流だったC/C++のスタイルを受け継ぎ、言語的にもすっきりさせたJavaは、多くの言語に影響を与えた。Javaの影響を受けC#が作られた。
一方でPerlなどスクリプト言語は当初からガベージコレクタを持っている。これは、スクリプト言語自体がメモリ管理といった面倒ごとからプログラマを解放することを目的として作られているからだ。同類のJavaScript、PHP、Ruby、Pythonなども同様の思想と共に、ガベージコレクタを受け継いでいる。
現在では、C#やJava、Objective-Cといった、性能が潤沢なコンピュータ向けの言語はガベージコレクタを持つようになる傾向にある。一方で、携帯電話やゲーム機といった、性能が低いコンピュータや、処理性能を必要とされる環境では、依然ガベージコレクタを使わない状態が続くと思われる。
- 日本語でGCについてまとめてあるサイト掲示板
31 ななしのよっしん
2022/05/08(日) 15:41:51 ID: Tzok5G7mn1
.NETのGCは任意で呼び出せるのでGC爆弾を避ける為にちゃんと定期的に呼び出そうな
特にデストラクタが定義されてる奴はDispose呼び忘れ回避の為にも
32 ななしのよっしん
2022/05/08(日) 19:11:09 ID: lp+7AOntjl
SwiftとObjective-Cはガベコレを敢えて採用せずARC(自動参照カウント)を使っているらしいが
ARCの優位点を教えてほしい
33 ななしのよっしん
2024/08/13(火) 08:58:18 ID: tyVSDuumnL
自動参照カウントもGCの実装方法の一つだよ
マーク&スイープだけがGCじゃない
急上昇ワード改
最終更新:2025/12/16(火) 07:00
最終更新:2025/12/16(火) 07:00
ウォッチリストに追加しました!
すでにウォッチリストに
入っています。
追加に失敗しました。
ほめた!
ほめるを取消しました。
ほめるに失敗しました。
ほめるの取消しに失敗しました。