リモートワーク・ご商談等のオンライン対応について

ギークスジョブの掲載案件はリモートワークでの参画がご相談可能です。
また、現在実施している個別説明会、各種イベント、顧客企業様との商談打ち合わせはオンラインでご対応いただけます。

5分で分かるガベージコレクションの仕組み

作成日:2020/09/24(木) 最終更新日:2024/12/25(水) TECH

5分で分かるガベージコレクションの仕組み

ITエンジニアであれば「ガベージコレクション」という言葉を知っている、もしくは耳にしたことがある人は多いかと思います。ただ、「もちろん聞いたことはあるし、だいたいどんなものであるかは分かっているけど、実際のところそれをちゃんと説明できるほどにはよく理解していない」という方も多いのではないでしょうか。
本記事では、「ガベージコレクション」の正体を分かりやすく解説致します。

合わせて読みたい記事

ガベージコレクションとは?

今回はガベージコレクションを「掃除のおばちゃん」に例えてご説明致します。実はガベージコレクションとは、プログラムにおける掃除のおばちゃんのような存在なのです。なぜ、ガベージコレクションが掃除のおばちゃんに例えられるかを、「プログラム実行時にメモリ上ではどのようなことが起こっているか」の解説を通して、お伝え致します。

プログラムが動作する際には以下2つのステップを踏みます。


  • プログラム処理に必要な情報をメモリ上に読み込む
  • 読み込んだ情報をもとに、処理を実行する

読み込まれた情報は、処理をしている間はもちろん必要なものですが、その処理が終わってしまうと途端に不要になります。つまり「メモリに残されたゴミ」のような状態になってしまうのです。

ガベージコレクションとは?の画像

そこで登場するのが、掃除のおばちゃんこと「ガベージコレクション」となります。
こちらは、「プログラムが確保したメモリ領域のうち、不要になった箇所だけを解放してくれる」機能となります。必要に応じてメモリ領域を割り当て・解放等することを「メモリ管理」と言います。

しかしガベージコレクションは、プログラマがメモリ管理のためのコードをわざわざ書かなくても、「この領域は必要かそうでないか」を自動的にチェックしてくれます。JavaやPHPのような高級言語は、こちらのガベージコレクションを標準機能として備えていることが多いです。

そもそも「メモリ」とは?メモリの基礎①

そもそも「メモリ」とは?メモリの基礎①の画像

掃除のおばちゃんこと「ガベージコレクション」が掃除する「メモリに残されたゴミ」ですが、そもそもメモリとは何なのでしょうか。


メモリとは、パソコンやスマートフォンなどのデバイスでデータを「一時的」に保存する記憶装置のことです。この「一時的」という点が重要です。他にも情報を保存する場所として、SSDやHDDといったストレージがあります。ストレージはメモリと違いデータを一時的ではなく、長期間にわたって保管する記憶装置です。それでは、なぜ一時的な保存にメモリが必要なのでしょうか。


その理由は、CPUがデータにアクセスする際の速度差にあります。メモリはストレージよりも高速にデータへアクセスできるため、頻繁に使うデータの一時的な保管場所として利用されます。メモリは処理の効率化に欠かせない役割を果たしているのです。


メモリとストレージの関係性や役割を説明する際によく使われる例えが「机と本棚の例え」です。
ストレージを本棚に例えると、メモリはその本を広げて作業する机に相当します。
メモリ=机と考えると、机の上に複数の本を広げることで効率的に作業が進み、必要な情報にすぐアクセスできます。

一方で、毎回必要な本を本棚(ストレージ)から取り出すとなると、作業効率が落ちてしまうのは明らかです。
ただし、机の広さには限りがあるため、すべての本を机の上に置いて作業することはできません。
さらに、机の上が本でいっぱいになってしまうと、かえって作業が進みにくくなることもあります。そのため、必要な本だけを一時的に机の上に広げ、使い終わったら片づける等の工夫が必要となってきます。


このようにメモリは、片付ける工夫は必要ですが、効率的なデータアクセスを可能にする「一時的な作業スペース」としての役割を担っているのです。


「処理が終わったのにもかかわらず、メモリを開放し忘れる」というミスが起こりかねないのです。この状態になってしまうと、プログラムが実行されるたびにメモリ上に余分なデータが溜まり続けます。

「スタック領域」と「ヒープ領域」とは?メモリの基礎②

さらにメモリに関して深堀っていきます。次はメモリの「スタック領域」と「ヒープ領域」について解説します。前述の説明でメモリを机に例えて話しましたが、スタック領域とヒープ領域も同じように机を例に考えていきます。

スタック領域とは

スタック領域はメモリを机とすると、「すぐに使う作業スペース」部分がスタック領域と考えるとわかりやすいです。
スタック領域は、机の上の限られたスペースで、すぐに使う道具や資料を置く部分です。このスペースには一時的に使うものが次々と置かれていきます。そして、使い終わったらすぐに片づけて、別の新しい作業をする準備を整える場所です。


例えば、勉強するときに本やノートを机に積み重ねて使うように、新しい作業が発生するたびに必要な道具を積み重ね、終わったものから順に片づけていく流れです。また、スタック領域は意識せずに自動で片づけられるため、整理を気にする必要がありません。なお、この自動片づけは「ガベージコレクション=掃除のおばちゃん」のおかげではなく、スタック領域の仕組みによるものです。

ヒープ領域とは

同じようにヒープ領域を例えると、それは「自由に使える大きな引き出し」のようなものと考えるとわかりやすいです。
引き出し(ヒープ領域)には、あまり使わない大きな本や、必要なときに取り出して使う本を入れておくことができます。作業が増えてくると、引き出しに閉まっていた本を取り出して作業したり、新しい本を引き出しに閉まったり、と自由な使い方ができるスペースがヒープ領域です。


ヒープ領域の大事なポイントは、使い終わったら手動できちんと片づける必要があることです。スタック領域とは違い、自動で片付けされません。引き出しに物を入れたら、使い終わった後には片づけ(メモリの解放)をする必要があります。もし、使い終わった物を引き出しに入れたままにすると、引き出しがいっぱいになり、新しい本を置けなくなることがあります。後述しますが、これが「メモリリーク」と呼ばれる問題です。


このメモリリークを解決するために登場したのが、「ガベージコレクション=掃除のおばちゃん」です。

ガベージコレクションが登場する前

ガベージコレクションが登場する前の画像

それでは、ガベージコレクションが登場する前にはどのようにメモリ管理が行われていたのでしょうか。


実は、プログラマ自身がメモリの確保と解放を行うためのコードを都度書いていたのです。現在でも、ガベージコレクションの搭載されていないC言語などでは、プログラマはその処理を都度行っています。
しかし、この方法はバグを多く生み出します。


「処理が終わったのにもかかわらず、メモリを解放し忘れる」というミスが起こりかねないのです。この状態になってしまうと、プログラムが実行されるたびにメモリ上に余分なデータが溜まり続けます。


そうして最終的には、使用可能なメモリを食いつぶしてしまい、プログラムが動作不可能な状態となってしまいます。これを「メモリリーク」と呼びます。メモリリークは熟練したプログラマでも回避するのは困難でした。
しかし、ガベージコレクションによってメモリ管理を常に意識しなくてもよくなり、プログラミングの難易度が大幅に下がったのです。

Scavenge GCとFull GC

ガベージコレクションには、大きくわけて2つの種類があります。それは、「Scavenge GC(スキャベンジ・ジーシー)」と「Full GC(フル・ジーシー)」です。
それぞれの違いを順に解説します。

Scavenge GC

前述した、机の引き出しに当たる「ヒープ領域」ですが、このヒープ領域はさらに「New領域」と「Old領域」に分けられます。


New領域には生成されたあとすぐに廃棄されるオブジェクトが入り、Old領域にはさらに長い寿命を持つオブジェクトが入ります。Scavenge GCはそのうちNew領域のみを対象としたもので、比較的短時間で終了します。


掃除のおばちゃんを例にする場合、「引き出しの一番上に置かれた、使い捨てのものだけをさっと片づける」ような状態です。

Full GC

一方のFull GCは、Old領域を含む全領域を対象にしたものとなります。
(状況によっては、一部領域が除外されます)Scavenge GCほど高頻度では発生しないかわりに、終了するまでに時間がかかります。


これも掃除のおばちゃんを例にする場合、「机のすべての引き出しを開けて、奥にある不要なものも含めて徹底的に片づける」といったイメージになります。

Javaのガベージコレクションの仕組み

Javaのガベージコレクションの仕組みは前述のScavenge GCとFull GCの基本的な概念そのものです。


Javaでは、ヒープ領域をYoung領域とOld領域に分けて管理し、それぞれに適したガベージコレクションを行う仕組みが採用されています。「Young領域」は、「New領域」とほぼ同じ概念ですが、JavaではYoung領域という表現が一般的です。


Young(New)領域は新しく生成された短命のオブジェクトを一時的に保管する場所でScavenge GC(Minor GC)によって定期的にメモリが解放されます。その中で使用が続くオブジェクトはOld領域に移動されます。


Old領域はYoung領域から移動された長寿命のオブジェクトを保管する場所です。Old領域が対象となるFull GCは、処理が重くシステムに影響を与えやすいため、Old領域の管理はパフォーマンスを維持するために重要です。

JavaのGC(ガベージコレクション)アルゴリズム

Javaには、アプリケーションの目的や使用環境に応じて複数のGCアルゴリズムが用意されています。主なGCアルゴリズムは次の通りです。

Serial GC

単一スレッドでガベージコレクションを行います。単純な構造のため、少ないメモリで動作する一方、シングルスレッドでしか動作しないため、他の処理が一時的に停止しやすく、パフォーマンスに影響が出やすいという特徴があります。小規模なアプリケーションに適しています。

Parallel GC

複数のスレッドを使って並行にGCを行い、処理速度を高めます。これにより、短時間で多くのメモリを解放でき、スループット(全体的な処理効率)も向上します。パフォーマンスを重視する場合に向いていますが、瞬間的なレスポンスが求められる場面では、他のアルゴリズムがより適していることもあります。

G1 GC(Garbage First GC)

特に大規模なアプリケーション向けに設計されたGCです。メモリを小さなブロックに分割し、不要なブロックを優先的に回収することで効率的にメモリを管理します。Young領域とOld領域の両方をバランスよく掃除し、長時間の停止を防ぐため、安定したパフォーマンスが得られます。大規模かつレスポンスの安定が重要なアプリケーションに適しています。


これらのGCアルゴリズムをアプリケーションの特性に合わせて選ぶことで、Javaアプリケーションのメモリ管理が効率化され、全体のパフォーマンス向上につながります。ちなみに今回取り上げたのは3つのアルゴリズムですが、JavaのGCアルゴリズムはまだ他にも複数あります。

Pythonのガベージコレクションの仕組み

Pythonのガベージコレクションは、参照カウント方式を基本とし、循環参照の解決のために世代別GCを採用しています。世代別GCでは、オブジェクトを世代ごとに分類し、長く使われるオブジェクトほどガベージコレクションの頻度を下げて管理します。

世代0(新しい世代)

生成されて間もないオブジェクトが置かれる領域で、最も頻繁にGCが行われます。多くのオブジェクトはここで使用されなくなり、すぐにメモリから解放されます。

世代1・世代2(古い世代)

世代1にはやや長く使われるオブジェクト、世代2にはさらに長く使われるオブジェクトが保管されます。世代が進むほどGCの頻度が減り、パフォーマンスが安定します。特に世代2は、Javaでいう「Old領域」に相当し、システム全体の負荷を軽減する役割もあります。


このように、Pythonの世代別GCでは短命なオブジェクトを早めに処理し、長命なオブジェクトは頻繁なガベージコレクションから守ることで、効率的なメモリ管理が実現されています。

ガベージコレクションによるパフォーマンスへの影響

Webアプリケーションのように、「ほんの少しだけレスポンスが遅くなるのは許容できるけれど、システムそのものが数秒~数十秒間停止してしまうのは避けなければいけない」という条件がある場合、Scavenge GCは発生してよくても、Full GCが発生することは何としても防がなければいけません。
それは非常に重い処理であるため、システムのパフォーマンスに大きな影響を与えてしまうからです。


Full GCを抑えるには、具体的には次のような点に注意することが必要になります。

オブジェクトをできるだけ使い回さないこと

オブジェクトの寿命が長くなるため、Old領域に割り当てられる可能性が高くなります。Old領域が増えれば増えるほど、Full GCが発生しやすいのです。

新しいオブジェクトを大量に使用する場合は、New領域を大きめにとること

プログラムの起動オプションなどで指定可能です。
これも同じように、Old領域に割り当てられるオブジェクトを少なくする意図があります。
※ただし一部のゲームアプリのように、わずかの処理速度遅延が許容できないときには、このケースが当てはまらない場合があります。

おわりに

おわりにの画像

普段あまり意識することのない「ガベージコレクション」という機能。
そこには、私たちの代わりにせっせとゴミを回収してくれている掃除のおばちゃんが住んでいます。


耳をすませば、無機質なソースコードのすき間から、おばちゃんの声が聞こえてくるかもしれませんよ。


ギークスジョブはITフリーランス専門エージェントとして20年以上にわたり、ITフリーランスのご支援を行っています。
フリーランスを初めて検討される方はもちろん、現在フリーランスとしての今後に不安を感じている方、今よりもっと充実したフリーランス生活を楽しみたい方は、ぜひお気軽にご相談ください。ITフリーランス専任のキャリアアドバイザーがマンツーマンでサポートいたします。


▽ 無料登録(エントリー)はこちら
https://geechs-job.com/entry


まだフリーランスになることに迷いがある方へは、独立のご相談から承ります。これまでのご経歴やキャリアの目標をお伺いしながら、お一人おひとりに寄り添ったキャリアプランのご提案をいたします。


▽ 独立相談会への無料エントリーはこちら
東京:https://geechs-job.com/event/details/1
大阪:https://geechs-job.com/event/details/2
福岡:https://geechs-job.com/event/details/3
名古屋:https://geechs-job.com/event/details/189

その他のおすすめ記事

5分で分かるJavaデザインパターン|ITフリーランスをサポートするギークスジョブ

ITフリーランスの方のための『お役立ち情報』をご紹介しています。この情報のテーマは5分で分かるJavaデザインパターンです。geechs job(ギークスジョブ)では、「フリーに生きる」ためのノウハウをご紹介し、ご希望のキャリアやライフプランを実現できるように、サポート致します!

ITフリーランスの案件探しならgeechs job

IT業界・企業情報の専門知識を持ったコーディネーターが、あなたに合う案件をご紹介。
ITエンジニアとしてのキャリアに弾みを付けませんか?

  • ・独立して新しいキャリアを築きたい
  • ・スキルを磨いて、更なる高みを目指したい
  • ・今よりも高い報酬を

ITフリーランスエージェントのgeechs jobが、あなたの未来に向けて伴走します。

シェア

いきなりフリーランスとして活動するのは不安...という方へ

業界・専門知識の豊富なコーディネーターが、関東、関西、福岡で無料セミナーを実施しています

こんなお悩みはありませんか?

  • 自分のスキルでフリーランスになれるか不安
  • 安定した収入を得られるのか不安
  • 税金や保険などの手続きがどうなるのか知りたい

まずは、ギークスジョブの無料イベントに参加してみませんか?
まだ本格的に活動する予定がない方も、情報収集の手段として活用されています。
不安や小さな不明点を解消する場として、是非ご利用くださいませ。

イベント一覧を見る
上に戻る