您好,登錄后才能下訂單哦!
這篇文章主要介紹“CPython中的垃圾收集器怎么使用”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“CPython中的垃圾收集器怎么使用”文章能幫助大家解決問題。
CPython 的垃圾收集器(簡稱GC)是 Python 內置的為了解決循環引用問題的方法。默認情況下,它總是在后臺運行,并且每隔一段時間就會發揮它的魔力,所以你不必擔心循環引用物會堵塞你的內存。
垃圾收集器被設計為從 CPython 的工作內存中找到并刪除循環引用對象。它通過以下方式完成這一工作。
檢測循環引用的對象
調用最終的 __del__ 方法
它從每個對象中刪除指針(以此來解決循環問題),只有當循環在步驟 2 之后仍然是孤立的
在這個過程完成后,以前在循環中的每個對象現在的引用計數都是 0 ,因此此對象將從內存中刪除。
雖然它是自動工作的,但實際上我們可以把它作為一個模塊從標準庫中導入。舉例如下:
import gc
CPython 的垃圾收集器會跟蹤內存中存在的各種對象--但不是所有的對象。我們可以實例化一些對象,看看垃圾收集器是否會收集它們。
>>> gc.is_tracked("a string")
False
>>> gc.is_tracked(["a", "list"])
True
如果一個對象可以包含指針,這就使它有能力形成循環引用結構的一部分--而這正是垃圾檢測器存在的目的,即檢測和拆除。在 Python 中這樣的對象通常被稱為 "容器對象"。
所以,垃圾收集器需要知道任何有可能作為循環引用的一部分而存在的對象。字符串不能,所以 "一個字符串 "不會被垃圾收集器追蹤。列表(正如我們已經看到的)能夠包含指針,因此 ['a', 'list'] 被跟蹤。
用戶定義的類的任何實例也將被垃圾收集器跟蹤,因為我們總是可以在它們身上設置任意的屬性(指針)。
>>> Wade = MyNameClass("Wade")
>>> gc.is_tracked(Wade)
True
所以,垃圾收集器知道所有有可能形成循環引用的對象。它怎么知道是否已經形成循環引用呢?
它也知道每個對象中的所有指針,以及它們所指向的位置。我們可以看到這個動作。
>>> my_list = ["a", "list"]
>>> gc.get_referents(my_list)
['list', 'a']
get_referents 方法(也稱為遍歷方法)接收一個對象,并返回它所包含的對象指針的列表(它的引用)。因此,上面的列表包含指向其每個元素的指針,這些元素都是字符串。
讓我們在一個對象的循環中看看 get_referents 方法(雖然還不是一個循環引用,因為這些對象仍然可以從命名空間中被訪問)。
>>> jane = MyNamedClass("Jane")
>>> bob = MyNamedClass("Bob")
>>> jane.friend = bob
>>> bob.friend = jane
>>> gc.get_referents(bob)
[{'name': 'bob', 'friend': <__main__.MyNamedClass object at 0x7ff29a095d60>}, <class '__main__
在這個循環中,我們可以看到由 bob 指向的對象包含指向以下內容的指針:它的屬性字典,包含 bob 的名字 (bob) 和它的朋友 (同樣由 jane 指向的 MyNamedClass 實例) 。bob 對象也有一個指向類對象本身的指針,因為 bob.class 將返回那個類對象。
當垃圾收集器運行時,它檢查它所知道的每個對象(也就是當你調用 gc.is_tracked 時返回True的任何對象)是否可以從命名空間到達。它通過跟蹤來自命名空間的所有指針,以及這些指針所指向的對象中的指針,以此類推,直到它建立起所有可從代碼中訪問的東西的整個視圖。
如果在做完這些之后,GC 發現存在一些不能從命名空間到達的對象,那么它可以把這些對象清除掉。
記住,任何仍在內存中的對象必須有一個非零的引用計數,否則它們會因為引用計數而被刪除。對于那些無法到達但仍有非零引用計數的對象,它們必須是循環引用的一部分,這就是為什么我們如此關心這些發生的可能性。
讓我們回到引用循環,jane 和 bob,通過從命名空間中移除指針,把這個循環變成一個循環的隔離。
>>> del jane
>>> del bob
現在,我們已經了解了垃圾收集器所要解決的確切情況。我們可以通過調用 gc.collect() 來觸發手動垃圾收集。
>>> gc.collect()
Deleting Bob!
Deleting Jane!
4
默認情況下,垃圾收集器會每隔一段時間自動執行這個動作(因為越來越多的對象在CPython運行時被創建和銷毀)。
在上面的代碼片段中,我們看到的輸出包含了來自 MyNamClass 的 __del__ 方法的打印語句,在最后有一個數字--在這個例子中,是 4。 這個數字是由垃圾收集器本身輸出的,它告訴我們有多少對象被移除。
關于“CPython中的垃圾收集器怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。