自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Python引用計(jì)數(shù)與相關(guān)析構(gòu)函數(shù)的實(shí)際操作步驟

開(kāi)發(fā) 后端
當(dāng)Python引用計(jì)數(shù)減為0的時(shí)侯,應(yīng)該與對(duì)象所對(duì)應(yīng)的相關(guān)析構(gòu)函數(shù)有時(shí)會(huì)被調(diào)用于Python中,文本就是對(duì)Python引用計(jì)數(shù)在具體應(yīng)用的相關(guān)介紹。

在C或是在C++中,相關(guān)人員在實(shí)際的操作中是可以自由的運(yùn)用,但是在某些方面可以說(shuō)是存在一些罪惡,就這一缺陷,我們可以用Python引用計(jì)數(shù)在其方面有一個(gè)解決的方案,以下是文章的具體介紹。

在權(quán)利的面,程序員必須負(fù)責(zé)將申請(qǐng)的內(nèi)存釋放,并釋放無(wú)效指針。可以說(shuō),這一點(diǎn)正是萬(wàn)惡之源,大量?jī)?nèi)存泄露和懸空指針的bug由此而生,如黃河泛濫一發(fā)不可收拾。

現(xiàn)代的開(kāi)發(fā)語(yǔ)言中一般都選擇由語(yǔ)言本身負(fù)責(zé)內(nèi)存的管理和維護(hù),即采用了垃圾收集機(jī)制,比如Java和C#。垃圾收集機(jī)制使開(kāi)發(fā)人員從維護(hù)內(nèi)存分配和清理的繁重工作中解放出來(lái),但同時(shí)也剝奪了程序員與內(nèi)存親密接觸的機(jī)會(huì),并付出了一定的運(yùn)行效率作為代價(jià)。#t#

現(xiàn)在看來(lái),隨著垃圾收集機(jī)制的完善,對(duì)時(shí)間要求不是非常高的程序完全可以通過(guò)使用垃圾收集機(jī)制的語(yǔ)言來(lái)完成,這部分程序占了現(xiàn)存的大多數(shù)的程序。這樣做的好處是提高了開(kāi)發(fā)效率,并降低了bug發(fā)生的幾率。Python同樣也內(nèi)建了垃圾收集機(jī)制,代替程序員進(jìn)行繁重的內(nèi)存管理工作,而引用計(jì)數(shù)正是Python垃圾收集機(jī)制的一部分。

Python通過(guò)對(duì)一個(gè)對(duì)象的引用計(jì)數(shù)的管理來(lái)維護(hù)對(duì)象在內(nèi)存中的存在與否。我們知道在Python中每一個(gè)東西都是一個(gè)對(duì)象,都有一個(gè)ob_refcnt變量。這個(gè)變量維護(hù)著該對(duì)象的引用計(jì)數(shù),從而也最終決定著該對(duì)象的創(chuàng)建與消亡。

在Python中,主要是通過(guò)Py_INCREF(op)和Py_DECREF(op)兩個(gè)宏來(lái)增加和減少一個(gè)對(duì)象的Python引用計(jì)數(shù)。當(dāng)一個(gè)對(duì)象的引用計(jì)數(shù)減少到0之后,Py_DECREF將調(diào)用該對(duì)象的析構(gòu)函數(shù)來(lái)釋放該對(duì)象所占有的內(nèi)存和系統(tǒng)資源。注意這里的“析構(gòu)函數(shù)”借用了C++的詞匯,實(shí)際上這個(gè)析構(gòu)動(dòng)作是通過(guò)在對(duì)象對(duì)應(yīng)的類型對(duì)象中定義的一個(gè)函數(shù)指針來(lái)指定的,就是那個(gè)tp_dealloc。

如果熟悉設(shè)計(jì)模式中的Observer模式,就可以看到,這里隱隱約約透著Observer模式的影子。在ob_refcnt減為0之后,將觸發(fā)對(duì)象銷毀的事件。從Python的對(duì)象體系來(lái)看,各個(gè)對(duì)象提供了不同的事件處理函數(shù),而事件的注冊(cè)動(dòng)作正是在各個(gè)對(duì)象對(duì)應(yīng)的類型對(duì)象中靜態(tài)完成的。

PyObject中的ob_refcnt是一個(gè)32位的整形變量,這實(shí)際蘊(yùn)含著Python所做的一個(gè)假設(shè),即對(duì)一個(gè)對(duì)象的引用不會(huì)超過(guò)一個(gè)整形變量的最大值。一般情況下,如果不是惡意代碼,這個(gè)假設(shè)顯然是成立的。

需要注意的是,在Python的各種對(duì)象中,類型對(duì)象是超越引用計(jì)數(shù)規(guī)則的。類型對(duì)象“跳出三界外,不再五行中”,永遠(yuǎn)不會(huì)被析構(gòu)。每一個(gè)對(duì)象中指向類型對(duì)象的指針不被視為對(duì)類型對(duì)象的引用。在每一個(gè)對(duì)象創(chuàng)建的時(shí)候,Python提供了一個(gè)_Py_NewReference(op)宏來(lái)將對(duì)象的Python引用計(jì)數(shù)初始化為1。

在Python的源代碼中可以看到,在不同的編譯選項(xiàng)下(Py_REF_DEBUG, Py_TRACE_ REFS),引用計(jì)數(shù)的宏還要做許多額外的工作。下面展示的代碼是Python在最終發(fā)行時(shí)這些宏所對(duì)應(yīng)的實(shí)際的代碼:

 

  1. [object.h]  
  2. #define _Py_NewReference(op) ((op)->ob_refcnt = 1)  
  3. #define _Py_Dealloc(op) ((*(op)->ob_type->tp_dealloc)((PyObject *)(op)))  
  4. #define Py_INCREF(op) ((op)->ob_refcnt++)  
  5. #define Py_DECREF(op) \  
  6. if (--(op)->ob_refcnt != 0) \  
  7. ; \  
  8. else \  
  9. _Py_Dealloc((PyObject *)(op))  
  10. /* Macros to use in case the object pointer may be NULL: */  
  11. #define Py_XINCREF(op) if ((op) == NULL) ; else Py_INCREF(op)  
  12. #define Py_XDECREF(op) if ((op) == NULL) ; else Py_DECREF(op)   

 

在一個(gè)對(duì)象的Python引用計(jì)數(shù)減為0時(shí),與該對(duì)象對(duì)應(yīng)的析構(gòu)函數(shù)就會(huì)被調(diào)用,但是要特別注意的是,調(diào)用析構(gòu)函數(shù)并不意味著最終一定會(huì)調(diào)用free釋放內(nèi)存空間,如果真是這樣的話,那頻繁地申請(qǐng)、釋放內(nèi)存空間會(huì)使Python的執(zhí)行效率大打折扣(更何況Python已經(jīng)多年背負(fù)了人們對(duì)其執(zhí)行效率的不滿)。

一般來(lái)說(shuō),Python中大量采用了內(nèi)存對(duì)象池的技術(shù),使用這種技術(shù)可以避免頻繁地申請(qǐng)和釋放內(nèi)存空間。因此在析構(gòu)時(shí),通常都是將對(duì)象占用的空間歸還到內(nèi)存池中。這一點(diǎn)在接下來(lái)對(duì)Python內(nèi)建對(duì)象的實(shí)現(xiàn)中可以看得一清二楚。

 

責(zé)任編輯:佚名 來(lái)源: 互聯(lián)網(wǎng)
相關(guān)推薦

2010-03-26 18:51:51

Python作用域

2010-03-12 15:29:19

Pythonexe

2010-03-24 16:25:18

Python源代碼

2010-04-21 17:09:17

Oracle安裝

2010-05-13 17:00:32

MySQL啟動(dòng)方法

2010-04-20 11:06:33

Oracle索引

2010-05-28 18:16:43

MySQL 操作日志

2010-06-01 15:54:46

MySQL-pytho

2010-03-10 19:00:20

Pythonnext函

2010-04-30 16:42:08

Oracle歸檔模式

2010-03-26 11:00:55

Python嵌入CC++

2010-05-27 14:35:25

MySQL批量導(dǎo)入

2020-11-10 08:45:35

Python

2010-07-21 15:22:07

2010-04-06 08:58:27

Oracle job

2010-05-12 13:45:25

Mysql 復(fù)制設(shè)置

2010-04-02 13:34:33

Oracle DBA

2010-03-23 17:24:08

Python遍歷目錄樹(shù)

2010-04-06 10:11:11

Oracle備份

2010-04-21 15:52:45

Oracle游標(biāo)
點(diǎn)贊
收藏

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