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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM