1. 程式人生 > 實用技巧 >Python如何釋放記憶體?

Python如何釋放記憶體?

功能說明

Python使用引用計數、分代演算法回收垃圾,引用計數操作方法:

  1. 物件被引用一次,其計數器+1
  2. 物件被del,其計數器-1
  3. 物件的引用計數為0時候會被回收

python的魔法方法__del__,類似java的finalize方法,會在物件被回收時執行。

實驗驗證

實驗1: 刪除僅引用一次的物件

步驟:

  1. 建立一個class,重寫__del__方法,列印資訊
  2. 建立該類例項,然後把它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

結果分析:

  1. 調完del命令,__del__方法被執行,物件立即被刪除(引用次數為0)
  2. 調完del命令後引用a被刪除(其引用的物件不一定被刪除,但是引用一定被刪除)

實驗2: 刪除被多次引用的物件

步驟:

  1. 在上面那個用例的基礎上,用多個引用引用A的物件
  2. 刪除其中一個引用,觀察物件是否被刪除

預期:

刪除一個引用,只是那個引用被刪除了,但是物件不會被刪除。

驗證程式碼:

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

結果分析:

  1. 調完del命令刪除a後,物件並沒有被刪除,通過其他引用b和c可以繼續訪問
  2. 物件在程序結束前被回收了,實際上不呼叫任何del,程序退出前A的例項都會被回收
  3. 推論:如果想回收A的例項,需要刪除所有它的引用(引用次數降到0)

以上驗證基於Python 3.7.7