【Python】ガベージコレクション

python_logo

さて、今日はPythonの縁の下の力持ち的な存在であるガベージコレクションについてまとめたいと思います。

普段私たちは変数が使い終わった後どうなるかなんて気にしてませんよね。

Pythonの中で使い終わった変数はどのように処理されているのでしょうか?

その使い終わったゴミ(変数)を片付けてくれるのがガベージコレクションなのです!

それではみていきましょう!

目次

  1. ガベージコレクションとは
  2. ガベージコレクションのメリット
  3. Tips・注意点

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

すでに使われていない変数をメモリ上から自動的に開放してくれる仕組みをガベージコレクションといいます。

オブジェクトはヘッダー領域に型情報とリファレンスカウンターを保持しています。

リファレンスカウンターとは、変数からどれだけ参照されているかというリファレンスの数を保持しています。

この リファレンスカウンターが0になるということは、そのオブジェクトはどの変数からも参照されていないこと分かります。

ガベージコレクターはリファレンスカウンターが0のオブジェクトをメモリから自動的に開放しているのです。

変数とオブジェクトの関係を忘れてしまった方は、下の記事をご参照ください!

ガベージコレクションのメリット

自動的にメモリを管理してくれるのが非常にプログラマーにとって楽なのです。

実はC言語のような低水準プログラマーだとメモリの管理もプログラマーが行います。しかも一々使い終わったら、それに対するコードを逐一書きます。

もし書き忘れてしまったら?おめでとうございます。メモリリークの原因になります。

こういったことを一々考えなくてすむ仕組みなのです!
そんなことより他の仕事で手がいっぱいですから、非常にありがたいです。

Tips・注意点

循環参照(問題

ただし、ガベージコレクションは万能ではありません。

Python2.0までは、循環参照の問題に悩まされていました。

循環参照とは、オブジェクトAがオブジェクトBをもっており、オブジェクトBがオブジェクトAをもっている状態です。

この状態になると変数からのリファレンスがなくても、リファレンスカウントはお互いがお互いのインスタンスを持つため0になりませんでした。
そうです。ガベージコレクションの対象とならないのです。

Python2.0からは循環検出のためのアルゴリズムが組み込まれ、定期的に実行することでこの問題を回避しようとしたのです。

ただし、パフォーマンスに問題を抱えており何度か修正が内部で行われていました。

参照:循環参照のガベージコレクション

安全なファイナライザーの実装

Python3.4からはさらにパワーアップしました。

実は、__del__が実装されているオブジェクトが循環参照を構成しているとガベージコレクションとなりませんでした。

これを解消するために、さらにアルゴリズムに処理を追加することで正常にガベージコレクションの対象とすることができるようになりました。

参照:PEP442 安全なオブジェクトファイナライザー

まとめ

いかがだったでしょうか?

大体のガベージコレクションについての動きについては把握していただけたでしょうか。

正直に申し上げますと少し私の理解が足りない部分があり、不明瞭な部分があると感じております。

また、コードがあったほうが分かりやすいと思いますので、理解を深めたらまた書き直します!

一応PEP442の理解の足しになりそうなコードが有りましたので以下に貼っておきますね

PEP 442, objects with a del() method don’t end up in gc.garbage anymore

以上になります。

みなさんのPythonライフがよりよくなるように祈っていますね!