<一覧に戻る

循環参照とは

循環参照とは、異なるオブジェクトが互いに参照し合う状態を指します。Pythonのメモリ管理において、循環参照が発生すると、ガベージコレクションのプロセスに影響を及ぼすことがあります。この教材では、循環参照の概念を理解し、Pythonにおける具体的な例を通じてその影響を探ります。

循環参照の基本概念

循環参照は、2つ以上のオブジェクトが互いを参照し合うことで形成されます。例えば、オブジェクトAがオブジェクトBを参照し、オブジェクトBがオブジェクトAを参照している場合、これが循環参照です。このような場合、オブジェクトAとBのいずれも外部から参照されていない場合、予想外のメモリリークを引き起こす可能性があります。

サンプルコード

以下のコードは、循環参照の例を示しています。

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

# ノードを生成
node1 = Node(1)
node2 = Node(2)

# 循環参照を作成
node1.next = node2
node2.next = node1

# 参照を解除する前にメモリの状態を確認
print("Node 1:", node1.value, "->", node1.next.value)
print("Node 2:", node2.value, "->", node2.next.value)

# 循環参照を解除
node1.next = None
node2.next = None

コードの解説

  1. Nodeクラスの定義:

    • Nodeクラスは、値を持つノードを表します。各ノードは次のノードへの参照を持つnext属性を持っています。
  2. ノードの生成:

    • node1node2という2つのノードを生成します。
  3. 循環参照の作成:

    • node1nextnode2に設定し、node2nextnode1に設定することで、互いに参照し合う循環参照を作成します。
  4. メモリの状態を確認:

    • print文を使って、各ノードの値と次のノードを表示します。この時点では、循環参照が正常に機能していることが確認できます。
  5. 循環参照の解除:

    • 循環参照を解除するために、node1.nextnode2.nextNoneに設定します。これによって、ノード同士の参照が解除され、メモリが解放される準備が整います。

循環参照が問題になる理由

循環参照が問題となるのは、Pythonがリファレンスカウント方式でメモリ管理を行っているためです。リファレンスカウントでは、オブジェクトへの参照の数が0になると、そのオブジェクトはガベージコレクションの対象としてマークされます。しかし、循環参照が存在する場合、参照の数は0にはならず、メモリが解放されない状態が続く可能性があります。

次のセクションでは、循環参照がメモリリークを引き起こす理由について詳しく見ていきます。

出力結果: