<一覧に戻る

世代別ガベージコレクションの概念

Pythonにおけるガベージコレクション(GC)は、メモリ管理の重要な側面です。その中でも「世代別ガベージコレクション」は、オブジェクトのライフサイクルに基づいて効率的にメモリを管理する手法です。この教材では、世代別ガベージコレクションの基本的な概念について学び、サンプルコードを通じてその理解を深めます。

世代別ガベージコレクションの基本概念

世代別ガベージコレクションは、オブジェクトを「世代」に分類し、それぞれの世代に応じて異なるガベージコレクションの戦略を適用する方法です。Pythonでは、オブジェクトは主に以下の3つの世代に分類されます。

  1. 世代0(Young Generation)

    • 新しく作成されたオブジェクトが配置される場所。
    • 短命なオブジェクトが多く、頻繁にガベージコレクションが行われる。
  2. 世代1(Middle Generation)

    • 世代0から昇格したオブジェクトが配置される。
    • 中程度の寿命を持つオブジェクトが多い。
  3. 世代2(Old Generation)

    • 世代1から昇格したオブジェクトが配置される。
    • 長寿命のオブジェクトが多く、ガベージコレクションの頻度は低い。

サンプルコード

次に、世代別ガベージコレクションの概念を実際に体験してみましょう。以下のコードは、オブジェクトを作成し、世代別ガベージコレクションの動作を観察するためのものです。

コードの実行には、数秒~10秒程度かかる場合があります。

import gc
import time

# オブジェクトを作成する関数
def create_objects(n):
    objects = []
    for i in range(n):
        # 新しいオブジェクトを作成
        obj = {"index": i}
        objects.append(obj)
    return objects

# メモリの状態を表示する関数
def print_memory_status():
    print(f"世代0のオブジェクト数: {gc.get_count()[0]}")
    print(f"世代1のオブジェクト数: {gc.get_count()[1]}")
    print(f"世代2のオブジェクト数: {gc.get_count()[2]}")

# メイン処理
if __name__ == "__main__":
    gc.collect()  # 初期のガベージコレクションを実行
    print("初期のメモリ状態:")
    print_memory_status()

    # 新しいオブジェクトを生成
    print("\nオブジェクトを生成中...")
    create_objects(10000)  # 10,000個のオブジェクトを作成

    print("オブジェクト生成後のメモリ状態:")
    print_memory_status()

    # 少し待ってから再度ガベージコレクションを実行
    time.sleep(2)
    gc.collect()
    print("\nガベージコレクション後のメモリ状態:")
    print_memory_status()

コードの解説

  1. モジュールのインポート:

    • gcモジュールはガベージコレクションの操作を行うためのものです。
    • timeモジュールは一時的に処理を停止させるために使用します。
  2. オブジェクト作成関数:

    • create_objects(n)関数は、指定された数の辞書オブジェクトを作成し、リストに格納して返します。
  3. メモリ状態表示関数:

    • print_memory_status()関数は、現在の世代ごとのオブジェクト数を表示します。
  4. メイン処理:

    • 初回のガベージコレクションを実行し、メモリの初期状態を表示。
    • 10,000個のオブジェクトを生成し、その後のメモリ状態を表示。
    • 一定時間待ってからガベージコレクションを再実行し、最終的なメモリ状態を表示。

このコードを実行することで、世代別ガベージコレクションがどのようにオブジェクトの寿命を管理し、メモリの使用状況に影響を与えるかを観察できます。特に、世代0のオブジェクトが多く生成される様子と、その後のガベージコレクションによってメモリがどのように解放されるかに注目してください。

出力結果: