Pythonは、メモリ管理のためにリファレンスカウントという仕組みを使用しています。これは、オブジェクトがどれだけ参照されているかを追跡する方法です。この教材では、オブジェクトの参照とリファレンスカウントの増減について学び、実際にコードを使ってその動作を確認します。
リファレンスカウントは、各オブジェクトがどれだけの参照を持っているかを示す整数値です。このカウントがゼロになると、そのオブジェクトはメモリから解放されます。以下のコードを使って、リファレンスカウントがどのように増減するかを見てみましょう。
import sys
# 新しいオブジェクトを生成
a = [] # 空のリストを作成
print(f'リスト a のリファレンスカウント: {sys.getrefcount(a)}')
# リファレンスカウントを増やす
b = a # a を b に代入
print(f'リスト a のリファレンスカウント: {sys.getrefcount(a)}')
# リファレンスカウントを減らす
del b # b を削除
print(f'リスト a のリファレンスカウント: {sys.getrefcount(a)}')
import sys
sys
モジュールをインポートします。sys
モジュールにはsys.getrefcount()
という関数が含まれ、引数として渡したオブジェクトの現在の参照カウント(リファレンスカウント)を取得できます。a = []
a
に代入します。a
は少なくとも1つの参照を持っています(a
自体の参照)。sys.getrefcount(a)
sys.getrefcount(a)
は、リストa
のリファレンスカウントを返します。b = a
b
に変数a
を代入すると、リストa
への参照が1つ増えます。del b
b
を削除すると、リストa
への参照が1つ減ります。a
のリファレンスカウントが1減少します。次に、リファレンスカウントがどのようにオブジェクトの寿命に影響を与えるかを見てみましょう。以下のコードを実行してみてください。
import sys
class MyClass:
def __init__(self, name):
self.name = name
obj1 = MyClass("Object 1")
print(f'obj1 のリファレンスカウント: {sys.getrefcount(obj1)}')
obj2 = obj1 # 参照を増やす
print(f'obj1 のリファレンスカウント: {sys.getrefcount(obj1)}')
obj3 = obj1 # さらに参照を増やす
print(f'obj1 のリファレンスカウント: {sys.getrefcount(obj1)}')
del obj2 # 参照を減らす
print(f'obj1 のリファレンスカウント: {sys.getrefcount(obj1)}')
del obj3 # さらに参照を減らす
print(f'obj1 のリファレンスカウント: {sys.getrefcount(obj1)}')
# obj1 を削除する前にリファレンスカウントを確認
print(f'obj1 の最終リファレンスカウント: {sys.getrefcount(obj1)}')
del obj1 # 最後の参照を削除
# obj1 を削除した後にアクセスしないようにする
# print(f'obj1 のリファレンスカウント: {sys.getrefcount(obj1)}') # これはコメントアウトまたは削除
class MyClass
MyClass
を定義しています。初期化メソッド __init__
でオブジェクトに名前を設定します。obj1 = MyClass("Object 1")
MyClass
のインスタンスを生成し、変数 obj1
に代入します。obj1
による参照が1つ作成されますが、sys.getrefcount
関数が呼び出されたときの一時参照も加わるため、リファレンスカウントは 2 になります。obj2 = obj1
とobj3 = obj1
obj1
を他の変数 obj2
と obj3
に代入することで、リファレンスカウントがそれぞれ1ずつ増加します。obj1
, obj2
, obj3
, 一時参照)。del obj2
とdel obj3
obj2
や obj3
を削除すると、obj1
のリファレンスカウントがそれぞれ1ずつ減少します。最終確認とdel obj1
obj1
を削除することで、リファレンスカウントがゼロになり、オブジェクトがメモリから解放されます。リファレンスカウントは、Pythonのメモリ管理において非常に重要な役割を果たしています。オブジェクトの参照が増減することで、その寿命が決まります。次回は、リファレンスカウントによるメモリ解放の仕組みについて学んでいきましょう。