新聞中心
使對(duì)象類(lèi)型支持循環(huán)垃圾回收
python 對(duì)循環(huán)引用的垃圾檢測(cè)與回收需要“容器”對(duì)象類(lèi)型的支持,此類(lèi)型的容器對(duì)象中可能包含其它容器對(duì)象。不保存其它對(duì)象的引用的類(lèi)型,或者只保存原子類(lèi)型(如數(shù)字或字符串)的引用的類(lèi)型,不需要顯式提供垃圾回收的支持。

站在用戶(hù)的角度思考問(wèn)題,與客戶(hù)深入溝通,找到城關(guān)網(wǎng)站設(shè)計(jì)與城關(guān)網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶(hù)體驗(yàn)好的作品,建站類(lèi)型包括:成都網(wǎng)站制作、做網(wǎng)站、外貿(mào)營(yíng)銷(xiāo)網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、申請(qǐng)域名、網(wǎng)絡(luò)空間、企業(yè)郵箱。業(yè)務(wù)覆蓋城關(guān)地區(qū)。
若要?jiǎng)?chuàng)建一個(gè)容器類(lèi),類(lèi)型對(duì)象的 tp_flags 字段必須包含 Py_TPFLAGS_HAVE_GC 并提供一個(gè) tp_traverse 處理的實(shí)現(xiàn)。如果該類(lèi)型的實(shí)例是可變的,還需要實(shí)現(xiàn) tp_clear 。
Py_TPFLAGS_HAVE_GC
設(shè)置了此標(biāo)志位的類(lèi)型的對(duì)象必須符合此處記錄的規(guī)則。為方便起見(jiàn),下文把這些對(duì)象稱(chēng)為容器對(duì)象。
容器類(lèi)型的構(gòu)造函數(shù)必須符合兩個(gè)規(guī)則:
-
必須使用 PyObject_GC_New() 或 PyObject_GC_NewVar() 為這些對(duì)象分配內(nèi)存。
-
初始化了所有可能包含其他容器的引用的字段后,它必須調(diào)用 PyObject_GC_Track() 。
同樣的,對(duì)象的釋放器必須符合兩個(gè)類(lèi)似的規(guī)則:
-
在引用其它容器的字段失效前,必須調(diào)用 PyObject_GC_UnTrack() 。
-
必須使用 PyObject_GC_Del() 釋放對(duì)象的內(nèi)存。
警告
如果一個(gè)類(lèi)型添加了 Py_TPFLAGS_HAVE_GC,則它 必須 實(shí)現(xiàn)至少一個(gè) tp_traverse 句柄或顯式地使用來(lái)自其一個(gè)或多個(gè)子類(lèi)的句柄。
當(dāng)調(diào)用 PyType_Ready() 或者 API 中某些間接調(diào)用它的函數(shù)例如 PyType_FromSpecWithBases() 或 PyType_FromSpec() 時(shí)解釋器就自動(dòng)填充 tp_flags, tp_traverse 和 tp_clear 字段,如果該類(lèi)型是繼承自實(shí)現(xiàn)了垃圾回收器協(xié)議的類(lèi)并且該子類(lèi) 沒(méi)有 包括 Py_TPFLAGS_HAVE_GC 旗標(biāo)的話。
TYPE *PyObject_GC_New(TYPE, PyTypeObject *type)
類(lèi)似于 PyObject_New() ,適用于設(shè)置了 Py_TPFLAGS_HAVE_GC 標(biāo)簽的容器對(duì)象。
TYPE *PyObject_GC_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size)
類(lèi)似于 PyObject_NewVar() ,適用于設(shè)置了 Py_TPFLAGS_HAVE_GC 標(biāo)簽的容器對(duì)象。
TYPE *PyObject_GC_Resize(TYPE, PyVarObject *op, Py_ssize_t newsize)
為 PyObject_NewVar() 所分配對(duì)象重新調(diào)整大小。 返回調(diào)整大小后的對(duì)象或在失敗時(shí)返回 NULL。 op 必須尚未被垃圾回收器追蹤。
void PyObject_GC_Track(PyObject *op)
Part of the Stable ABI.
把對(duì)象 op 加入到垃圾回收器跟蹤的容器對(duì)象中。對(duì)象在被回收器跟蹤時(shí)必須保持有效的,因?yàn)榛厥掌骺赡茉谌魏螘r(shí)候開(kāi)始運(yùn)行。在 tp_traverse 處理前的所有字段變?yōu)橛行Ш?,必須調(diào)用此函數(shù),通常在靠近構(gòu)造函數(shù)末尾的位置。
int PyObject_IS_GC(PyObject *obj)
如果對(duì)象實(shí)現(xiàn)了垃圾回收器協(xié)議則返回非零值,否則返回 0。
如果此函數(shù)返回 0 則對(duì)象無(wú)法被垃圾回收器追蹤。
int PyObject_GC_IsTracked(PyObject *op)
Part of the Stable ABI since version 3.9.
如果 op 對(duì)象的類(lèi)型實(shí)現(xiàn)了 GC 協(xié)議且 op 目前正被垃圾回收器追蹤則返回 1, 否則返回 0。
這類(lèi)似于 Python 函數(shù) gc.is_tracked()。
3.9 新版功能.
int PyObject_GC_IsFinalized(PyObject *op)
Part of the Stable ABI since version 3.9.
如果 op 對(duì)象的類(lèi)型實(shí)現(xiàn)了 GC 協(xié)議且 op 已經(jīng)被垃圾回收器終結(jié)則返回 1, 否則返回 0。
這類(lèi)似于 Python 函數(shù) gc.is_finalized()。
3.9 新版功能.
void PyObject_GC_Del(void *op)
Part of the Stable ABI.
釋放對(duì)象的內(nèi)存,該對(duì)象初始化時(shí)由 PyObject_GC_New() 或 PyObject_GC_NewVar() 分配內(nèi)存。
void PyObject_GC_UnTrack(void *op)
Part of the Stable ABI.
從回收器跟蹤的容器對(duì)象集合中移除 op 對(duì)象。 請(qǐng)注意可以在此對(duì)象上再次調(diào)用 PyObject_GC_Track() 以將其加回到被跟蹤對(duì)象集合。 釋放器 (tp_dealloc 句柄) 應(yīng)當(dāng)在 tp_traverse 句柄所使用的任何字段失效之前為對(duì)象調(diào)用此函數(shù)。
在 3.8 版更改: _PyObject_GC_TRACK() 和 _PyObject_GC_UNTRACK() 宏已從公有 C API 中移除。
tp_traverse 處理接收以下類(lèi)型的函數(shù)形參。
typedef int (*visitproc)(PyObject *object, void *arg)
Part of the Stable ABI.
傳給 tp_traverse 處理的訪問(wèn)函數(shù)的類(lèi)型。object 是容器中需要被遍歷的一個(gè)對(duì)象,第三個(gè)形參對(duì)應(yīng)于 tp_traverse 處理的 arg 。Python核心使用多個(gè)訪問(wèn)者函數(shù)實(shí)現(xiàn)循環(huán)引用的垃圾檢測(cè),不需要用戶(hù)自行實(shí)現(xiàn)訪問(wèn)者函數(shù)。
tp_traverse 處理必須是以下類(lèi)型:
typedef int (*traverseproc)(PyObject *self, visitproc visit, void *arg)
Part of the Stable ABI.
用于容器對(duì)象的遍歷函數(shù)。 它的實(shí)現(xiàn)必須對(duì) self 所直接包含的每個(gè)對(duì)象調(diào)用 visit 函數(shù),visit 的形參為所包含對(duì)象和傳給處理程序的 arg 值。 visit 函數(shù)調(diào)用不可附帶 NULL 對(duì)象作為參數(shù)。 如果 visit 返回非零值,則該值應(yīng)當(dāng)被立即返回。
為了簡(jiǎn)化 tp_traverse 處理的實(shí)現(xiàn),Python提供了一個(gè) Py_VISIT() 宏。若要使用這個(gè)宏,必須把 tp_traverse 的參數(shù)命名為 visit 和 arg 。
void Py_VISIT(PyObject *o)
如果 o 不為 NULL,則調(diào)用 visit 回調(diào)函數(shù),附帶參數(shù) o 和 arg。 如果 visit 返回一個(gè)非零值,則返回該值。 使用此宏之后,tp_traverse 處理程序的形式如下:
static intmy_traverse(Noddy *self, visitproc visit, void *arg){Py_VISIT(self->foo);Py_VISIT(self->bar);return 0;}
tp_clear 處理程序必須為 inquiry 類(lèi)型,如果對(duì)象不可變則為 NULL。
typedef int (*inquiry)(PyObject *self)
Part of the Stable ABI.
丟棄產(chǎn)生循環(huán)引用的引用。不可變對(duì)象不需要聲明此方法,因?yàn)樗麄儾豢赡苤苯赢a(chǎn)生循環(huán)引用。需要注意的是,對(duì)象在調(diào)用此方法后必須仍是有效的(不能對(duì)引用只調(diào)用 Py_DECREF() 方法)。當(dāng)垃圾回收器檢測(cè)到該對(duì)象在循環(huán)引用中時(shí),此方法會(huì)被調(diào)用。
控制垃圾回收器狀態(tài)
這個(gè) C-API 提供了以下函數(shù)用于控制垃圾回收的運(yùn)行。
Py_ssize_t PyGC_Collect(void)
Part of the Stable ABI.
執(zhí)行完全的垃圾回收,如果垃圾回收器已啟用的話。 (請(qǐng)注意 gc.collect() 會(huì)無(wú)條件地執(zhí)行它。)
返回已回收的 + 無(wú)法回收的不可獲取對(duì)象的數(shù)量。 如果垃圾回收器被禁用或已在執(zhí)行回收,則立即返回 0。 在垃圾回收期間發(fā)生的錯(cuò)誤會(huì)被傳給 sys.unraisablehook。 此函數(shù)不會(huì)引發(fā)異常。
int PyGC_Enable(void)
Part of the Stable ABI since version 3.10.
啟用垃圾回收器:類(lèi)似于 gc.enable()。 返回之前的狀態(tài),0 為禁用而 1 為啟用。
3.10 新版功能.
int PyGC_Disable(void)
Part of the Stable ABI since version 3.10.
禁用垃圾回收器:類(lèi)似于 gc.disable()。 返回之前的狀態(tài),0 為禁用而 1 為啟用。
3.10 新版功能.
int PyGC_IsEnabled(void)
Part of the Stable ABI since version 3.10.
查詢(xún)垃圾回收器的狀態(tài):類(lèi)似于 gc.isenabled()。 返回當(dāng)前的狀態(tài),0 為禁用而 1 為啟用。
3.10 新版功能.
網(wǎng)站標(biāo)題:創(chuàng)新互聯(lián)Python教程:使對(duì)象類(lèi)型支持循環(huán)垃圾回收
地址分享:http://www.dlmjj.cn/article/dpjejdd.html


咨詢(xún)
建站咨詢(xún)
