Python如何釋放記憶體?
阿新 • • 發佈:2020-07-25
功能說明
Python使用引用計數、分代演算法回收垃圾,引用計數操作方法:
- 物件被引用一次,其計數器+1
- 物件被
del
,其計數器-1 - 物件的引用計數為0時候會被回收
python的魔法方法__del__
,類似java的finalize
方法,會在物件被回收時執行。
實驗驗證
實驗1: 刪除僅引用一次的物件
步驟:
- 建立一個class,重寫
__del__
方法,列印資訊 - 建立該類例項,然後把它del掉,觀察是否有回收訊息
預期:
物件被回收。
驗證程式碼:
import time class A: def __del__(self): print("A instance deleted") a = A() del a time.sleep(3) print("sleep end") print(a)
輸出結果:
A instance deleted
sleep end
Traceback (most recent call last):
File "/Users/wuhf/PycharmProjects/cookdata/cookdata/__init__.py", line 16, in <module>
print(a)
NameError: name 'a' is not defined
結果分析:
- 調完del命令,
__del__
方法被執行,物件立即被刪除(引用次數為0) - 調完del命令後引用
a
被刪除(其引用的物件不一定被刪除,但是引用一定被刪除)
實驗2: 刪除被多次引用的物件
步驟:
- 在上面那個用例的基礎上,用多個引用引用A的物件
- 刪除其中一個引用,觀察物件是否被刪除
預期:
刪除一個引用,只是那個引用被刪除了,但是物件不會被刪除。
驗證程式碼:
import time class A: def __del__(self): print("A instance deleted") a = A() b=a c=a del a time.sleep(3) print("sleep end") print("b=%s" % str(b)) print("c=%s" % str(c)) try: print("a=%s" % str(a)) except Exception as e: print(e)
輸出結果:
sleep end
b=<__main__.A object at 0x101c154d0>
c=<__main__.A object at 0x101c154d0>
name 'a' is not defined
A instance deleted
結果分析:
- 調完del命令刪除a後,物件並沒有被刪除,通過其他引用b和c可以繼續訪問
- 物件在程序結束前被回收了,實際上不呼叫任何del,程序退出前A的例項都會被回收
- 推論:如果想回收A的例項,需要刪除所有它的引用(引用次數降到0)
以上驗證基於Python 3.7.7