
python垃圾回收機(jī)制
現(xiàn)在的高級語言如java,c#等,都采用了垃圾收集機(jī)制,而不再是c,c++里用戶自己管理維護(hù)內(nèi)存的方式。自己管理內(nèi)存極其自由,可以任意申請內(nèi)存,但如同一把雙刃劍,為大量內(nèi)存泄露,懸空指針等bug埋下隱患。
對于一個字符串、列表、類甚至數(shù)值都是對象,且定位簡單易用的語言,自然不會讓用戶去處理如何分配回收內(nèi)存的問題。
python里也同java一樣采用了垃圾收集機(jī)制,不過不一樣的是,python采用的是引用計(jì)數(shù)機(jī)制為主,標(biāo)記-清除和分代收集兩種機(jī)制為輔的策略。
引用計(jì)數(shù)機(jī)制:
python里每一個東西都是對象,它們的核心就是一個結(jié)構(gòu)體:PyObject
typedef struct_object {
int ob_refcnt;
struct_typeobject *ob_type;
}PyObject;
PyObject是每個對象必有的內(nèi)容,其中ob_refcnt就是做為引用計(jì)數(shù)。當(dāng)一個對象有新的引用時,它的ob_refcnt就會增加,當(dāng)引用它的對象被刪除,它的ob_refcnt就會減少
** #define Py_INCREF(op) ((op)->ob_refcnt++) //增加計(jì)數(shù)**
**define Py_DECREF(op) //減少計(jì)數(shù) **
if (--(op)->ob_refcnt != 0) \
; \
else \
__Py_Dealloc((PyObject *)(op))
引用計(jì)數(shù)為0時,該對象生命就結(jié)束了。
引用計(jì)數(shù)機(jī)制的優(yōu)點(diǎn):
1、簡單
2、實(shí)時性:一旦沒有引用,內(nèi)存就直接釋放了。不用像其他機(jī)制等到特定時機(jī)。實(shí)時性還帶來一個好處:處理回收內(nèi)存的時間分?jǐn)偟搅似綍r。
引用計(jì)數(shù)機(jī)制的缺點(diǎn):
1、維護(hù)引用計(jì)數(shù)消耗資源
2、循環(huán)引用
1
list1 = []
2
list2 = []
3
list1.append(list2)
4
list2.append(list1) , list1與list2相互引用,如果不存在其他對象對它們的引用,list1與list2的引用計(jì)數(shù)也仍然為1,所占用的內(nèi)存永遠(yuǎn)無法被回收,這將是致命的。
對于如今的強(qiáng)大硬件,缺點(diǎn)1尚可接受,但是循環(huán)引用導(dǎo)致內(nèi)存泄露,注定python還將引入新的回收機(jī)制。
上面說到python里回收機(jī)制是以引用計(jì)數(shù)為主,標(biāo)記-清除和分代收集兩種機(jī)制為輔。
1、標(biāo)記-清除機(jī)制
標(biāo)記-清除機(jī)制,顧名思義,首先標(biāo)記對象(垃圾檢測),然后清除垃圾(垃圾回收)。如圖1:
這里寫圖片描述
圖1
首先初始所有對象標(biāo)記為白色,并確定根節(jié)點(diǎn)對象(這些對象是不會被刪除),標(biāo)記它們?yōu)楹谏ū硎緦ο笥行В?。將有效對象引用的對象?biāo)記為灰色(表示對象可達(dá),
但它們所引用的對象還沒檢查),檢查完灰色對象引用的對象后,將灰色標(biāo)記為黑色。重復(fù)直到不存在灰色節(jié)點(diǎn)為止。最后白色結(jié)點(diǎn)都是需要清除的對象。
2、回收對象的組織
這里所采用的高級機(jī)制作為引用計(jì)數(shù)的輔助機(jī)制,用于解決產(chǎn)生的循環(huán)引用問題。而循環(huán)引用只會出現(xiàn)在“內(nèi)部存在可以對其他對象引用的對象”,比如:list,class等。
為了要將這些回收對象組織起來,需要建立一個鏈表。自然,每個被收集的對象內(nèi)就需要多提供一些信息,下面代碼是回收對象里必然出現(xiàn)的。
一個對象的實(shí)際結(jié)構(gòu)如圖2:
這里寫圖片描述
圖2
通過PyGC_Head的指針將每個回收對象連接起來,形成了一個鏈表,也就是在1里提到的初始化的所有對象。
3、分代技術(shù)
分代技術(shù)是一種典型的以空間換時間的技術(shù),這也正是java里的關(guān)鍵技術(shù)。這種思想簡單點(diǎn)說就是:對象存在時間越長,越可能不是垃圾,應(yīng)該越少去收集。
這樣的思想,可以減少標(biāo)記-清除機(jī)制所帶來的額外操作。分代就是將回收對象分成數(shù)個代,每個代就是一個鏈表(集合),代進(jìn)行標(biāo)記-清除的時間與代內(nèi)對象
存活時間成正比例關(guān)系。
從上面代碼可以看出python里一共有三代,每個代的threshold值表示該代最多容納對象的個數(shù)。默認(rèn)情況下,當(dāng)0代超過700,或1,2代超過10,垃圾回收機(jī)制將觸發(fā)。
0代觸發(fā)將清理所有三代,1代觸發(fā)會清理1,2代,2代觸發(fā)后只會清理自己。
下面是一個完整的收集流程:鏈表建立,確定根節(jié)點(diǎn),垃圾標(biāo)記,垃圾回收~
1、鏈表建立
首先,中里在分代技術(shù)說過:0代觸發(fā)將清理所有三代,1代觸發(fā)會清理1,2代,2代觸發(fā)后只會清理自己。在清理0代時,會將三個鏈表(代)鏈接起來,清理1代的時,會鏈接1,2兩代。在后面三步,都是針對的這個建立之后的鏈表。
2、確定根節(jié)點(diǎn)
圖1為一個例子。list1與list2循環(huán)引用,list3與list4循環(huán)引用。a是一個外部引用。
這里寫圖片描述
對于這樣一個鏈表,我們?nèi)绾蔚贸龈?jié)點(diǎn)呢。python里是在引用計(jì)數(shù)的基礎(chǔ)上又提出一個有效引用計(jì)數(shù)的概念。顧名思義,有效引用計(jì)數(shù)就是去除循環(huán)引用后的計(jì)數(shù)。
數(shù)據(jù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
訓(xùn)練與驗(yàn)證損失驟升:機(jī)器學(xué)習(xí)訓(xùn)練中的異常診斷與解決方案 在機(jī)器學(xué)習(xí)模型訓(xùn)練過程中,“損失曲線” 是反映模型學(xué)習(xí)狀態(tài)的核心指 ...
2025-09-19解析 DataHub 與 Kafka:數(shù)據(jù)生態(tài)中兩類核心工具的差異與協(xié)同 在數(shù)字化轉(zhuǎn)型加速的今天,企業(yè)對數(shù)據(jù)的需求已從 “存儲” 轉(zhuǎn)向 “ ...
2025-09-19CDA 數(shù)據(jù)分析師:讓統(tǒng)計(jì)基本概念成為業(yè)務(wù)決策的底層邏輯 統(tǒng)計(jì)基本概念是商業(yè)數(shù)據(jù)分析的 “基礎(chǔ)語言”—— 從描述數(shù)據(jù)分布的 “均 ...
2025-09-19CDA 數(shù)據(jù)分析師:表結(jié)構(gòu)數(shù)據(jù) “獲取 - 加工 - 使用” 全流程的賦能者 表結(jié)構(gòu)數(shù)據(jù)(如數(shù)據(jù)庫表、Excel 表、CSV 文件)是企業(yè)數(shù)字 ...
2025-09-19SQL Server 中 CONVERT 函數(shù)的日期轉(zhuǎn)換:從基礎(chǔ)用法到實(shí)戰(zhàn)優(yōu)化 在 SQL Server 的數(shù)據(jù)處理中,日期格式轉(zhuǎn)換是高頻需求 —— 無論 ...
2025-09-18MySQL 大表拆分與關(guān)聯(lián)查詢效率:打破 “拆分必慢” 的認(rèn)知誤區(qū) 在 MySQL 數(shù)據(jù)庫管理中,“大表” 始終是性能優(yōu)化繞不開的話題。 ...
2025-09-18DSGE 模型中的 Et:理性預(yù)期算子的內(nèi)涵、作用與應(yīng)用解析 動態(tài)隨機(jī)一般均衡(Dynamic Stochastic General Equilibrium, DSGE)模 ...
2025-09-17Python 提取 TIF 中地名的完整指南 一、先明確:TIF 中的地名有哪兩種存在形式? 在開始提取前,需先判斷 TIF 文件的類型 —— ...
2025-09-17CDA 數(shù)據(jù)分析師:解鎖表結(jié)構(gòu)數(shù)據(jù)特征價值的專業(yè)核心 表結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 規(guī)范存儲的結(jié)構(gòu)化數(shù)據(jù),如數(shù)據(jù)庫表、Excel 表、 ...
2025-09-17Excel 導(dǎo)入數(shù)據(jù)含缺失值?詳解 dropna 函數(shù)的功能與實(shí)戰(zhàn)應(yīng)用 在用 Python(如 pandas 庫)處理 Excel 數(shù)據(jù)時,“缺失值” 是高頻 ...
2025-09-16深入解析卡方檢驗(yàn)與 t 檢驗(yàn):差異、適用場景與實(shí)踐應(yīng)用 在數(shù)據(jù)分析與統(tǒng)計(jì)學(xué)領(lǐng)域,假設(shè)檢驗(yàn)是驗(yàn)證研究假設(shè)、判斷數(shù)據(jù)差異是否 “ ...
2025-09-16CDA 數(shù)據(jù)分析師:掌控表格結(jié)構(gòu)數(shù)據(jù)全功能周期的專業(yè)操盤手 表格結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 存儲的結(jié)構(gòu)化數(shù)據(jù),如 Excel 表、數(shù)據(jù) ...
2025-09-16MySQL 執(zhí)行計(jì)劃中 rows 數(shù)量的準(zhǔn)確性解析:原理、影響因素與優(yōu)化 在 MySQL SQL 調(diào)優(yōu)中,EXPLAIN執(zhí)行計(jì)劃是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 對象的 text 與 content:區(qū)別、場景與實(shí)踐指南 在 Python 進(jìn)行 HTTP 網(wǎng)絡(luò)請求開發(fā)時(如使用requests ...
2025-09-15CDA 數(shù)據(jù)分析師:激活表格結(jié)構(gòu)數(shù)據(jù)價值的核心操盤手 表格結(jié)構(gòu)數(shù)據(jù)(如 Excel 表格、數(shù)據(jù)庫表)是企業(yè)最基礎(chǔ)、最核心的數(shù)據(jù)形態(tài) ...
2025-09-15Python HTTP 請求工具對比:urllib.request 與 requests 的核心差異與選擇指南 在 Python 處理 HTTP 請求(如接口調(diào)用、數(shù)據(jù)爬取 ...
2025-09-12解決 pd.read_csv 讀取長浮點(diǎn)數(shù)據(jù)的科學(xué)計(jì)數(shù)法問題 為幫助 Python 數(shù)據(jù)從業(yè)者解決pd.read_csv讀取長浮點(diǎn)數(shù)據(jù)時的科學(xué)計(jì)數(shù)法問題 ...
2025-09-12CDA 數(shù)據(jù)分析師:業(yè)務(wù)數(shù)據(jù)分析步驟的落地者與價值優(yōu)化者 業(yè)務(wù)數(shù)據(jù)分析是企業(yè)解決日常運(yùn)營問題、提升執(zhí)行效率的核心手段,其價值 ...
2025-09-12用 SQL 驗(yàn)證業(yè)務(wù)邏輯:從規(guī)則拆解到數(shù)據(jù)把關(guān)的實(shí)戰(zhàn)指南 在業(yè)務(wù)系統(tǒng)落地過程中,“業(yè)務(wù)邏輯” 是連接 “需求設(shè)計(jì)” 與 “用戶體驗(yàn) ...
2025-09-11塔吉特百貨孕婦營銷案例:數(shù)據(jù)驅(qū)動下的精準(zhǔn)零售革命與啟示 在零售行業(yè) “流量紅利見頂” 的當(dāng)下,精準(zhǔn)營銷成為企業(yè)突圍的核心方 ...
2025-09-11