亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

python中的垃圾回收(GC)機(jī)制

 更新時(shí)間:2020年09月21日 08:43:45   作者:蒂米  
這篇文章主要介紹了python中的GC機(jī)制,幫助大家更好的理解和使用python,感興趣的朋友可以了解下

一、引用計(jì)數(shù)

Python 垃圾回收以引用計(jì)數(shù)為主,分代回收為輔。引用計(jì)數(shù)法的原理是每個(gè)對(duì)象維護(hù)一個(gè)ob_refcnt,用來記錄對(duì)象被引用的次數(shù),也就是用來追蹤有多少個(gè)引用指向了對(duì)象,當(dāng)發(fā)生以下四種情況的時(shí)候,對(duì)象的引用計(jì)數(shù)+1:

  • 對(duì)象被創(chuàng)建,比如:a = 14
  • 對(duì)象被引用,比如: b = a
  • 對(duì)象被作為參數(shù),傳給函數(shù),比如:func(a)
  • 對(duì)象作為容器中的一個(gè)元素,比如:List = {a, ”a” , ”b”, 2}

與上述情況相對(duì)應(yīng),當(dāng)發(fā)生以下四種情況時(shí),對(duì)象的引用計(jì)數(shù)-1:

對(duì)象的別名被顯式銷毀,比如:del a
對(duì)象的別名被賦予新的對(duì)象,比如:a = 26
對(duì)象離開它的作用域,比如 func() 執(zhí)行完畢時(shí),函數(shù)里面的所有局部變量的引用計(jì)數(shù)都會(huì)減 1
將元素從容器中刪除,或者容器被銷毀
當(dāng)對(duì)象的引用計(jì)數(shù)為 0 時(shí),它將被 Python 虛擬機(jī)回收。

在 Python 中一切皆對(duì)象,它們的核心是 Py_Object 結(jié)構(gòu)體,所有 Python 對(duì)象的頭部都包含該結(jié)構(gòu):

// object.h
#define PyObject_HEAD   
 _PyObject_HEAD_EXTRA  
 Py_ssize_t ob_refcnt;  
 struct _typeobject *ob_type;
​
typedef struct _object {
 PyObject_HEAD
} PyObject;

比如 int 類型的定義如下:

// intobj.h
typedef struct {
 PyObject_HEAD
 long ob_ival;
} PyIntObject;

簡而言之,PyObject 是每個(gè)對(duì)象必有的內(nèi)容,其中 ob_refcnt 是對(duì)象的引用計(jì)數(shù)。對(duì)象有新的引用時(shí),它的 ob_refcnt 會(huì)增加;當(dāng)對(duì)象的引用被刪除時(shí),ob_refcnt 會(huì)減少。當(dāng)引用計(jì)數(shù)為 0 時(shí),對(duì)象的生命周期就結(jié)束了。

// object.h
#define Py_INCREF(op) (    
 _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA 
 ((PyObject*)(op))->ob_refcnt++)
​
#define Py_DECREF(op)     
 do {      
 if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA 
 --((PyObject*)(op))->ob_refcnt != 0)  
  _Py_CHECK_REFCNT(op)   
 else      
 _Py_Dealloc((PyObject *)(op));   
 } while (0)

引用計(jì)數(shù)有很明顯的優(yōu)點(diǎn):

  • 高效
  • 運(yùn)行期沒有停頓,即實(shí)時(shí)性:對(duì)象一旦沒有引用,將直接被釋放。實(shí)時(shí)性還帶來一個(gè)好處是:處理回收內(nèi)存的時(shí)間分?jǐn)偟搅似綍r(shí)
  • 對(duì)象有確定的生命周期
  • 易于實(shí)現(xiàn)

原始的引用計(jì)數(shù)法也有明顯的缺點(diǎn):

  • 維護(hù)引用計(jì)數(shù)消耗資源,維護(hù)引用計(jì)數(shù)的次數(shù)和引用賦值成正比
  • 無法解決循環(huán)引用的問題

比如:

list1 = []
list2 = []
list1.append(list2)
list2.append(list1)

為了解決這兩個(gè)致命弱點(diǎn),Python 又引入了以下兩種 GC 機(jī)制。

二、標(biāo)記-清除

『標(biāo)記-清除(Mark-Sweep)』算法是一種基于追蹤回收(tracing GC)技術(shù)實(shí)現(xiàn)的垃圾回收算法。它分為兩個(gè)階段:第一階段是標(biāo)記階段,GC 會(huì)給所有『活動(dòng)對(duì)象』打上標(biāo)記;第二階段是回收沒有標(biāo)記的『非活動(dòng)對(duì)象』。那么 GC 如何判斷哪些是活動(dòng)對(duì)象、哪些是非活動(dòng)對(duì)象呢?

對(duì)象之間通過引用(指針)連在一起,構(gòu)成一個(gè)有向圖。對(duì)象是有向圖的頂點(diǎn),引用關(guān)系是有向圖的弧。從根對(duì)象(root object)出發(fā),遍歷有向圖,將可達(dá)的(reachable)對(duì)象標(biāo)記為活動(dòng)對(duì)象,不可達(dá)的對(duì)象就是要被清除的非活動(dòng)對(duì)象。根對(duì)象是全局變量、調(diào)用棧、寄存器。

在上圖中,把小黑圈視為全局變量,也就是把它作為 root object,從小黑圈出發(fā),對(duì)象 1 可直達(dá),那么它將被標(biāo)記,對(duì)象 2、3 可間接到達(dá),也會(huì)被標(biāo)記,而 4 和 5 不可達(dá),因此 1、2、3 是活動(dòng)對(duì)象,4 和 5 是非活動(dòng)對(duì)象,會(huì)被 GC 回收。

標(biāo)記清除算法作為 Python 的輔助垃圾回收技術(shù),主要用于處理容器對(duì)象,比如 list、dict、tuple、instance 等,因?yàn)樽址?shù)值等原子類型的對(duì)象不可能造成循環(huán)引用問題。Python 使用雙向鏈表將容器對(duì)象組織起來。不過這種簡單粗暴的標(biāo)記清除算法也有明顯的缺點(diǎn):清除非活動(dòng)對(duì)象前,必須順序掃描整個(gè)堆內(nèi)存,哪怕只剩下小部分非活動(dòng)對(duì)象,也要掃描所有對(duì)象。

三,分代回收

分代回收是一種以空間換時(shí)間的操作方式,Python 將內(nèi)存根據(jù)對(duì)象的存活時(shí)間劃分為不同的集合,每個(gè)集合稱為一個(gè)代,Python 將內(nèi)存分為了 3 代,分別為年輕代(第 0 代)、中年代(第 1 代)、老年代(第 2 代),它們對(duì)應(yīng)是 3 個(gè)鏈表,垃圾回收頻率隨著對(duì)象存活時(shí)間的增大而減小。新創(chuàng)建的對(duì)象都會(huì)被分配到年輕代,當(dāng)年輕代鏈表的節(jié)點(diǎn)總數(shù)達(dá)到上限時(shí),Python 垃圾收集機(jī)制就會(huì)被觸發(fā),把可以被回收的對(duì)象回收掉,而不能被回收的對(duì)象會(huì)被移到中年代去,依此類推,老年代中的對(duì)象是存活時(shí)間最久的對(duì)象,甚至存活于整個(gè)系統(tǒng)的生命周期內(nèi)。分代回收建立在標(biāo)記清除的基礎(chǔ)之上,分代回收同樣作為 Python 處理容器對(duì)象的輔助垃圾回收技術(shù)。

以上就是python中的GC機(jī)制的詳細(xì)內(nèi)容,更多關(guān)于python GC的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python一行代碼實(shí)現(xiàn)生成和讀取二維碼

    Python一行代碼實(shí)現(xiàn)生成和讀取二維碼

    二維碼被稱為快速響應(yīng)碼,可能看起來很簡單,但它們能夠存儲(chǔ)大量數(shù)據(jù)。無論掃描二維碼時(shí)包含多少數(shù)據(jù),用戶都可以立即訪問信息。本文將用一行Python代碼實(shí)現(xiàn)二維碼的讀取與生成,需要的可以參考一下
    2022-02-02
  • Python封裝成可帶參數(shù)的EXE安裝包實(shí)例

    Python封裝成可帶參數(shù)的EXE安裝包實(shí)例

    今天小編就為大家分享一篇Python封裝成可帶參數(shù)的EXE安裝包實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • Pytorch模型遷移和遷移學(xué)習(xí),導(dǎo)入部分模型參數(shù)的操作

    Pytorch模型遷移和遷移學(xué)習(xí),導(dǎo)入部分模型參數(shù)的操作

    這篇文章主要介紹了Pytorch模型遷移和遷移學(xué)習(xí),導(dǎo)入部分模型參數(shù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • centos 自動(dòng)運(yùn)行python腳本和配置 Python 定時(shí)任務(wù)

    centos 自動(dòng)運(yùn)行python腳本和配置 Python 定時(shí)任務(wù)

    這篇文章主要介紹了centos 自動(dòng)運(yùn)行python腳本和配置 Python 定時(shí)任務(wù),文章內(nèi)容介紹詳細(xì),需要的小伙伴可以參考一下,希望對(duì)你有所幫助
    2022-03-03
  • python使用pil生成縮略圖的方法

    python使用pil生成縮略圖的方法

    這篇文章主要介紹了python使用pil生成縮略圖的方法,涉及Python使用pil模塊操作圖片的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-03-03
  • 一篇文章帶你入門Python正則表達(dá)式

    一篇文章帶你入門Python正則表達(dá)式

    這篇文章主要介紹了Python中正則表達(dá)式的詳細(xì)教程,正則表達(dá)式是Python學(xué)習(xí)進(jìn)階當(dāng)中的重要內(nèi)容,需要的朋友可以參考下
    2021-10-10
  • Python中hashlib模塊的摘要算法詳解

    Python中hashlib模塊的摘要算法詳解

    這篇文章主要介紹了Python中hashlib模塊的摘要算法詳解,摘要算法又稱哈希算法、散列算法,它通過一個(gè)函數(shù),把任意長度的數(shù)據(jù)轉(zhuǎn)換為一個(gè)長度固定的數(shù)據(jù)串,通常用16進(jìn)制的字符串表示,需要的朋友可以參考下
    2023-08-08
  • Python字典的概念及常見應(yīng)用實(shí)例詳解

    Python字典的概念及常見應(yīng)用實(shí)例詳解

    這篇文章主要介紹了Python字典的概念及常見應(yīng)用,結(jié)合實(shí)例形式詳細(xì)的分析了Python字典的概念、原理、創(chuàng)建、常見操作函數(shù)與使用注意事項(xiàng),需要的朋友可以參考下
    2019-10-10
  • 詳解Python的Lambda函數(shù)與排序

    詳解Python的Lambda函數(shù)與排序

    本篇文章主要是介紹了Python的Lambda函數(shù)與排序,簡單的介紹了Lambda函數(shù)的用法和排序,有需要的朋友可以了解一下。
    2016-10-10
  • python實(shí)現(xiàn)控制電腦鼠標(biāo)和鍵盤,登錄QQ的方法示例

    python實(shí)現(xiàn)控制電腦鼠標(biāo)和鍵盤,登錄QQ的方法示例

    這篇文章主要介紹了python實(shí)現(xiàn)控制電腦鼠標(biāo)和鍵盤,登錄QQ的方法,涉及Python基于Button,Controller,Key模塊針對(duì)鍵盤、鼠標(biāo)的控制相關(guān)操作技巧,需要的朋友可以參考下
    2019-07-07

最新評(píng)論