Section 7 / 12
リファレンスカウントによるメモリ解放
Pythonは自動的にメモリ管理を行いますが、その背後には「リファレンスカウント」という仕組みがあります。この教材では、リファレンスカウントによるメモリ解放の概念を理解し、実際のコードを通じてその動作を確認します。
リファレンスカウントとは
リファレンスカウントは、オブジェクトの参照が何回行われているかをカウントする仕組みです。各オブジェクトは、そのオブジェクトを参照する変数やデータ構造の数を追跡します。リファレンスカウントが0になると、オブジェクトは不要と判断され、メモリが解放されます。
サンプルコード
以下のサンプルコードを使って、リファレンスカウントの動作を確認します。
import sys
class MyObject:
def __init__(self, value):
self.value = value
# オブジェクトを作成
obj1 = MyObject(10)
print(f'obj1のリファレンスカウント: {sys.getrefcount(obj1)}')
# obj1を別の変数に代入
obj2 = obj1
print(f'obj1のリファレンスカウント: {sys.getrefcount(obj1)}')
print(f'obj2のリファレンスカウント: {sys.getrefcount(obj2)}')
# obj1の参照を削除
del obj1
print(f'obj2のリファレンスカウント: {sys.getrefcount(obj2)}')
# obj2の参照を削除
del obj2
# ここでobj2のリファレンスカウントは0になり、メモリが解放される
コード解説
-
class MyObject- クラス
MyObjectを定義し、コンストラクタ__init__でオブジェクトの属性valueを設定します。
- クラス
-
オブジェクト作成
obj1 = MyObject(10)によって、MyObjectのインスタンスを生成し、変数obj1に代入します。- この時点で、
obj1による参照が1つ作成されます。ただし、sys.getrefcount(obj1)を呼び出す際の一時参照が加わるため、リファレンスカウントは 2 と表示されます。
-
別の変数に代入
obj2 = obj1を実行すると、obj1が参照しているオブジェクトへの参照が増加し、リファレンスカウントが1増加します。- この状態ではリファレンスカウントは 3 になります(
obj1,obj2, 一時参照)。
-
del obj1del obj1によって、obj1が削除されますが、obj2がまだオブジェクトを参照しているため、リファレンスカウントが1減少します。- この時点でリファレンスカウントは 2 になります(
obj2と一時参照)。
-
del obj2del obj2によって、すべての参照が削除されます。- リファレンスカウントが0になり、オブジェクトがメモリから解放されます。
- この段階でリファレンスカウントを確認するコードは含まれていませんが、オブジェクトへの参照が完全に無くなります。
まとめ
リファレンスカウントは、Pythonにおけるメモリ管理の基本的な部分です。この仕組みを理解することで、Pythonがどのようにメモリを管理しているかをより深く理解できるようになります。次のステップでは、リファレンスカウントの限界や循環参照の問題について考えていきましょう。