<一覧に戻る

リファレンスカウントとは

Pythonは、メモリ管理のためにリファレンスカウント(参照カウント)を使用しています。リファレンスカウントとは、オブジェクトがメモリ内でどのくらいの数の参照(リファレンス)を持たれているかを追跡する仕組みです。具体的には、オブジェクトが生成されると、そのオブジェクトに対するリファレンスカウントが1になります。新しい参照が作られるたびにカウントが増加し、参照が削除されるとカウントが減少します。

この仕組みにより、メモリの自動管理が行われ、オブジェクトがもはや必要でなくなったときに自動的にメモリを解放することが可能になります。

リファレンスカウントの基本的な動作

以下のサンプルコードを通じて、リファレンスカウントの基本的な動作を理解しましょう。

import sys

class MyClass:
    def __init__(self, value):
        self.value = value

# オブジェクトの生成
obj1 = MyClass(10)

# リファレンスカウントを表示
print(f"obj1のリファレンスカウント: {sys.getrefcount(obj1)}")  # sysモジュールを使用

# 新しい参照を作成
obj2 = obj1
print(f"obj1のリファレンスカウント: {sys.getrefcount(obj1)}")

# 参照を削除
del obj2
print(f"obj1のリファレンスカウント: {sys.getrefcount(obj1)}")

コードの解説

  1. クラスの定義

    • MyClassというクラスを定義し、初期化メソッド__init__valueという属性を設定しています。このクラスは、リファレンスカウントの実験に使用するだけのシンプルな構造です。
  2. オブジェクトの生成

    • obj1 = MyClass(10)MyClassのインスタンスを生成しています。この時点で、Python内部では少なくとも1つの参照が存在します。
    • 注意: Pythonでは、sys.getrefcount()を使用すると、実際のリファレンスカウントよりも1多い値が返されます。これは、getrefcount関数に引数を渡すことで、一時的な参照が追加されるためです。
  3. リファレンスカウントの確認

    • sys.getrefcount(obj1)を使用してobj1のリファレンスカウントを確認します。
    • 初回の出力は通常「2」になります。これはobj1自身の参照と、sys.getrefcount関数呼び出し時の一時的な参照を含むためです。
  4. 新しい参照の作成

    • obj2 = obj1を実行すると、obj1の参照がもう1つ増えます。このとき、リファレンスカウントが1増加します。
    • この状態でリファレンスカウントを確認すると「3」と表示されます。
      obj1の参照、obj2の参照、そして関数呼び出し時の一時的な参照の合計)
  5. 参照の削除

    • del obj2を実行すると、obj2が削除され、obj1の参照が1つ減少します。この状態でリファレンスカウントを確認すると「2」と表示されます。
    • 削除後もobj1は有効であるため、引き続き使用可能です。

まとめ

リファレンスカウントは、Pythonのメモリ管理において非常に重要な役割を果たしています。この仕組みにより、オブジェクトの使用状況に応じてメモリが効率的に管理され、プログラマーが手動でメモリを解放する必要が少なくなります。しかし、リファレンスカウントには限界があり、特に循環参照の問題が存在します。この問題については次のセクションで詳しく説明します。

出力結果: