偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Python 垃圾回收機(jī)制中的引用計數(shù)

開發(fā) 前端
很明顯,引用計數(shù)本身并不足以保持運(yùn)行時的工作內(nèi)存中沒有無用的、不可回收的對象。這就是CPython的垃圾收集器發(fā)揮作用的地方。

Python 中的 __del__ 魔法方法,也被稱為對象的終結(jié)者,是一個在對象即將被從內(nèi)存中移除之前被調(diào)用的方法。它實際上并不做從內(nèi)存中刪除對象的工作,我們將在后面看到它是如何發(fā)生的。相反,這個方法是用來做任何在對象被移除前需要發(fā)生的清理工作。例如,關(guān)閉對象在創(chuàng)建時打開的任何文件。

在本節(jié)中,我們將使用下面這個類作為例子。

class MyNameClass:
def __init__(self, name):
self.name = name

def __del__(self):
print(f"Deleting {self.name}!")

在上面的例子中,我們已經(jīng)定義了我們的類在初始化時接受一個名字的輸入,當(dāng)調(diào)用 finaliser 時,它會通過打印相關(guān)實例的名字讓我們知道。這樣,我們就可以了解到哪些對象被從內(nèi)存中刪除,以及何時被刪除。

那么,CPython 什么時候會決定從內(nèi)存中刪除一個對象呢?有兩種方式(從CPython 3.10 開始)會發(fā)生這種情況:引用計數(shù)和垃圾回收。

引用計數(shù)

如果我們在 Python 中有一個指向某個對象的指針,那就是對該對象的引用。對于一個給定的對象 a ,CPython 會跟蹤有多少其他東西指向 a 。如果這個計數(shù)器達(dá)到零,就可以安全地從內(nèi)存中刪除這個對象,因為沒有其他東西在使用它。讓我們看一個例子。

>>> Harward = MyNameClass("Harward")
>>> del Harward
Deleting Harward!
>>>

在這里,我們創(chuàng)建了一個新的對象(MyNamedClass("Harward")),并創(chuàng)建了一個指向它的指針(Harward =)。然后,當(dāng)我們刪除 Harwade 時,我們刪除了這個引用,MyNamedClass 實例現(xiàn)在的引用計數(shù)為 0。 所以,CPython 決定從內(nèi)存中刪除它--而且,就在這之前,它的 __del__ 方法被調(diào)用,打印出了我們看到的上面的信息。

如果我們對一個對象創(chuàng)建了多個引用,我們將不得不擺脫所有的引用,以便使該對象被刪除。

>>> bob = MyNameClass("Bob")
>>> bob_two = bob # creating a new pointer to the same object
>>> del bob # this doesn't cause the object to be removed...
>>> del bob_two # ... but this does
Deleting Bob!

當(dāng)然,我們的 MyNamedClass 實例本身可以包含指針--畢竟它們是任意的 Python 對象,我們可以給它們添加任何我們喜歡的屬性。讓我們看一個例子。

>>> jane = MyNamedClass("Jane")
>>> bob = MyNamedClass("Bob")
>>> jane.friend = bob # now the "Jane" object contains a pointer to the "Bob" object...
>>> bob.friend = jane

我們在上面的代碼片斷中所做的是設(shè)置了一些循環(huán)引用。名字為 Jane 的對象包含一個指向名字為 Bob 的對象的指針,反之亦然。當(dāng)我們做下面的事情時,情況就變得有趣了。

>>> del jane
>>> del bob

我們現(xiàn)在已經(jīng)刪除了從命名空間到對象的指針?,F(xiàn)在,我們完全不能訪問那些 MyNameClass 對象了--但我們并沒有收到告訴我們它們即將被刪除的打印信息。這是因為這些對象仍有引用,包含在彼此之間,因此它們的引用計數(shù)不是 0 。

我們在這里創(chuàng)建的是一個循環(huán)隔離體;在這個結(jié)構(gòu)中,每個對象在循環(huán)中至少有一個引用,使其保持活力,但循環(huán)中的所有對象都不能從命名空間中被訪問。

循環(huán)隔離的直觀表現(xiàn)

下面是我們創(chuàng)建一個循環(huán)隔離時的直觀表現(xiàn)。

首先,我們創(chuàng)建兩個對象,每個對象在命名空間中都有一個名字。

圖片

接下來,我們通過在每個對象上添加一個指針來連接我們的兩個對象。

圖片

最后,我們通過刪除兩個對象的原始名稱來從命名空間中刪除指針。在這一點(diǎn)上,這兩個對象從名字空間中是不可訪問的,但每個對象都包含一個指向另一個對象的指針,所以它們的引用計數(shù)不是零。

圖片

所以,很明顯,引用計數(shù)本身并不足以保持運(yùn)行時的工作內(nèi)存中沒有無用的、不可回收的對象。這就是CPython的垃圾收集器發(fā)揮作用的地方。

責(zé)任編輯:武曉燕 來源: 宇宙之一粟
相關(guān)推薦

2017-10-12 12:41:11

PHP圾回收機(jī)制變量容器

2017-06-12 17:38:32

Python垃圾回收引用

2017-08-17 15:40:08

大數(shù)據(jù)Python垃圾回收機(jī)制

2021-05-27 21:47:12

Python垃圾回收

2017-03-03 09:26:48

PHP垃圾回收機(jī)制

2010-09-25 15:33:19

JVM垃圾回收

2011-07-04 16:48:56

JAVA垃圾回收機(jī)制GC

2009-06-23 14:15:00

Java垃圾回收

2021-11-05 15:23:20

JVM回收算法

2024-10-28 13:18:54

2010-09-25 15:26:12

JVM垃圾回收

2010-09-16 15:10:24

JVM垃圾回收機(jī)制

2021-12-07 08:01:33

Javascript 垃圾回收機(jī)制前端

2010-10-13 10:24:38

垃圾回收機(jī)制JVMJava

2011-06-28 10:19:40

C#開發(fā)

2015-06-04 09:38:39

Java垃圾回收機(jī)

2011-06-28 12:39:34

Java垃圾回收

2020-02-09 17:23:17

Python數(shù)據(jù)字典

2020-11-10 08:45:35

Python

2009-12-09 17:28:34

PHP垃圾回收機(jī)制
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號