欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python垃圾回收機制(GC)原理解析

 更新時間:2019年12月30日 08:32:47   作者:你沒有想象的那么重要  
這篇文章主要介紹了python垃圾回收機制(GC)原理解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

這篇文章主要介紹了python垃圾回收機制(GC)原理解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

  今天想跟大家分享的是關(guān)于python的垃圾回收機制,雖然本人這會對該機制沒有很深入的了解, 但是本著熱愛分享的原則,還是囫圇吞棗地坐下記錄分享吧, 萬一分享的過程中開竅了呢.哈哈哈.

  首先還是做一下概述吧: 我們都知道, 在做python的語言編程中, 相較于java, c++, 我們似乎很少去考慮到去做垃圾回收,內(nèi)存釋放的工作, 其實是python內(nèi)部已經(jīng)做了相應(yīng)的回收機制, 不用我們自己操心去做內(nèi)存釋放.但是還是有必要了解一下.可以更加深入的了解python這門優(yōu)美的語言的魅力.

一、概述:

  python的GC模塊主要運用了“引用計數(shù)(reference counting)”來跟蹤和回收垃圾。在引用計數(shù)的基礎(chǔ)上,還可以通過標記清除(mark and sweep)解決容器(這里的容器值指的不是docker,而是數(shù)組,字典,元組這樣的對象)對象可能產(chǎn)生的循環(huán)引用的問題。通過“分代回收(generation collection)”以空間換取時間來進一步提高垃圾回收的效率。

二、垃圾回收三種機制

  1、引用計數(shù)

  在Python中,大多數(shù)對象的生命周期都是通過對象的引用計數(shù)來管理的, 廣義上講,它也是一種垃圾回收機制,而且是一種最直觀最簡單的垃圾回收機制。

  原理:當(dāng)一個對象被創(chuàng)建引用或者被復(fù)制的時候,對象的引用計數(shù)會加一,當(dāng)一個對象的引用被銷毀時,對象的引用計數(shù)會減一,當(dāng)對象的引用計數(shù)減為0的時候,就意味著對象已經(jīng)沒有被任何人使用了,可以將其所占用的內(nèi)存釋放了。

  雖然引用計數(shù)必須在每次分配和釋放內(nèi)存的時候加入管理引用計數(shù)的這個動作,然而與其他主流垃圾收集機制相比, 最大的一個優(yōu)點是實時性, 及任何內(nèi)存,一旦沒有指向他的引用,就會立即被回收,其他的垃圾回收機制必須在某種特殊條件下(內(nèi)存分配失敗)才能進行無效內(nèi)存的回收。

  執(zhí)行效率問題: 引用計數(shù)機制帶來的維護引用計數(shù)帶來的額外操作與python運行中所運行的內(nèi)存分配和釋放,引用賦值的次數(shù)是成正比的。相比其他機制,比如“標記-清除”,“停止-復(fù)制”,是一個弱點,因為這些技術(shù)所帶來的操作基本上只是與待回收的數(shù)量有關(guān)。

  引用計數(shù)還存在的一個致命的弱點是循環(huán)引用,這使得垃圾回收機制從來沒有將引用計數(shù)包含在內(nèi)。這就需要我們用新的方法了, 即標記清除。

  2、標記清除

標記清除主要是用來解決循環(huán)引用產(chǎn)生的問題的,循環(huán)引用只會在容器對象中才會產(chǎn)生,比如數(shù)組、字典、元組等,首先是為了追蹤對象,需要每個容器對象維護兩個額外的指針,用來將容器對象組成一個鏈表,指針分別指向前后兩個容器對象,這樣就可以將對象的循環(huán)引用環(huán)摘除,就可以得出兩個對象的有效計數(shù)。

問題說明:

  循環(huán)引用可以使得一組對象的引用計數(shù)不是0, 然而這些對象實際上并沒有被外部對象所引用,這就意味著不會再有人使用這組對象, 應(yīng)該回收這組對象所占用的內(nèi)存空間,然而由于相互引用的存在,每一個對象的引用計數(shù)不為0,因為這些對象所占用的內(nèi)存永遠不會被釋放。比如下面的代碼:

a = [1, 2]
b = [3, 4]
a.append(b)
b.append(a)
del a
del b
# B
c = [3, 5]
d = [2, 4]
c.append(d)
d.append(c)
del c

OKAY,現(xiàn)在就這個做一下解釋,這是個集中營, 一個是root object(鏈表),另一個是unreachable鏈表。

對于上面的第一組, 在未執(zhí)行del語句的時候,a,b的引用計數(shù)都是2(init + append= 2),但是在DEL執(zhí)行完畢之后,a,b的引用次數(shù)互相減一。a,b陷入循環(huán)引用的圈子中,然后標記清除算法開始出來做事,找到其中一端a,開始拆a,b的引用環(huán)(我們從a出發(fā),因為它對B有一個引用,則將B的引用計數(shù)減一,然后順著引用到達B,因為B有一個對A的引用,同樣將A的引用減一,這樣就完成了循環(huán)引用對象之間的對象環(huán)摘除), 去掉以后發(fā)現(xiàn)a,c循環(huán)引用變成了0,所以a,b就被處理到unreachable鏈表中直接被做掉。

對于第二組,簡單一看d取環(huán)后引用計數(shù)還是1,但是a取環(huán)后就是0了這時的c已經(jīng)進入了unreachable的鏈表中,被判了死刑,但是此時在root表中還有d,d還在引用著c,如果c被搞掉,世界就沒有了正義。root鏈表中的d會被引用檢測引用了c,如果c沒了,那么b也就涼涼了,所以c又拉回到了root鏈表中。

解剖這兩個鏈表的原因是現(xiàn)在在unreachable中可能存在被root鏈表中的對象,直接或者間接引用的對象,這些對象是不能被回收的,一旦在標記的過程中,發(fā)現(xiàn)這樣的對象就將其移動到root鏈表中,完成標記后,unreachable鏈表中剩下的就是名副其實的垃圾對象了,接下來垃圾回收只需要限制在unreachable鏈表中即可。

  3、分代回收

背景:分代回收技術(shù)是上個世紀80年代初發(fā)展起來的一種垃圾回收機制,經(jīng)過研究表明:無論使用何總語言開發(fā)無論開發(fā)的是何種類型,何種規(guī)模的程序,都存在這樣一點相同之處, 即:一定比例的內(nèi)存塊的生存周期都比較短,通常是幾百萬條指令的時間,然而剩下的內(nèi)存塊,生存周期比較長,甚至?xí)囊婚_始直到程序結(jié)束。

從前面的“標記-清除”這樣的垃圾回收機制來看,這種垃圾收集機制帶來的額外操作實際上與系統(tǒng)中總的內(nèi)存塊的數(shù)量是相關(guān)的,當(dāng)要回收的內(nèi)存塊越多時,垃圾檢測帶來的額外操作就越多,而垃圾回收所帶來的額外操作就越少,反值則相反。為了提高垃圾的收集效率,采用“空間換時間”的策略。

原理: 將系統(tǒng)紅所有內(nèi)存塊根據(jù)其存活時間劃分為不同的集合每一個集合就稱為一個“代”,垃圾收集的頻率隨著代的存活時間的增大而減少。也即,活的時間越長的對象就越不可能是垃圾,就應(yīng)該減少對它的垃圾收集頻率,衡量的標準就是這個對象經(jīng)過的垃圾收集次數(shù)越多,該對象存活的時間就越長。

例如:

  當(dāng)某些內(nèi)存塊M經(jīng)過了3次垃圾回收的清洗之后還是存活著的時候,就將內(nèi)存塊M劃到一個集合A中去,當(dāng)垃圾收集開始工作時,大多數(shù)情況只是針對集合B進行垃圾回收,而對集合A進行垃圾回收要隔相當(dāng)長一段時間才進行,這就使得垃圾收集機制要處理的內(nèi)存少了,效率自然就提高了。這個過程中集合B中的某些內(nèi)存塊由于存活時間長會被轉(zhuǎn)移到A中, 當(dāng)然A中實際上也存在一些垃圾,這些垃圾回收會因為這種分帶機制而延遲。 在python中,一共有三代,也即維護3條鏈表(generation 0, 1, 2)

  • 0代表幼兒對象。
  • 1代表青年對象。
  • 2代表老年對象。

依據(jù)弱代假說(越年輕的越容易死掉)

新生的對象放在0代,對象在0代的第一次垃圾收集機制中活了過來, 那么久將其放到第1代里面了,同理,可能會被放到第2代。GC每代垃圾回收處罰的閾值可以自己設(shè)置(目前我不知道怎么設(shè)置/苦笑)。

這些就是目前的python的垃圾回收機制了。

下面的是 內(nèi)存池以及調(diào)優(yōu)手段:

內(nèi)存池:

python的內(nèi)存機制呈現(xiàn)金字塔形狀,-1, -2層主要由操作系統(tǒng)進行操作。

第0層是C中的malloc, free等內(nèi)存分配和釋放函數(shù)進行操作

第一層和第二層是內(nèi)存池,有python借口函數(shù),PyMem_Malloc函數(shù)實現(xiàn),當(dāng)對象小于256K時候由該層直接分配內(nèi)存,

第三層是最上層,也即我們對python對象的直接操作。

調(diào)優(yōu)手段:

1、手動垃圾回收

2、避免循環(huán)運用

3、提高垃圾回收閾值

希望上面這些能對大家有所幫助。謝謝支持?。?! 

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 12步教你理解Python裝飾器

    12步教你理解Python裝飾器

    或許你已經(jīng)用過裝飾器,它的使用方式非常簡單但理解起來困難(其實真正理解的也很簡單),想要理解裝飾器,你需要懂點函數(shù)式編程的概念,python函數(shù)的定義以及函數(shù)調(diào)用的語法規(guī)則等,感興趣的小伙伴們可以參考一下
    2016-02-02
  • opencv實現(xiàn)答題卡識別

    opencv實現(xiàn)答題卡識別

    這篇文章主要為大家詳細介紹了opencv實現(xiàn)答題卡識別,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Python貪吃蛇游戲編寫代碼

    Python貪吃蛇游戲編寫代碼

    這篇文章主要為大家詳細介紹了Python貪吃蛇游戲的編寫代碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • scrapy+flask+html打造搜索引擎的示例代碼

    scrapy+flask+html打造搜索引擎的示例代碼

    本文主要介紹了scrapy+flask+html打造搜索引擎的示例代碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 詳解Python多線程Selenium跨瀏覽器測試

    詳解Python多線程Selenium跨瀏覽器測試

    本篇文章主要介紹了Python多線程Selenium跨瀏覽器測試,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-04-04
  • Python四大金剛之元組詳解

    Python四大金剛之元組詳解

    這篇文章主要介紹了Python的元組,小編覺得這篇文章寫的還不錯,需要的朋友可以參考下,希望能夠給你帶來幫助
    2021-10-10
  • Python 合并拼接字符串的方法

    Python 合并拼接字符串的方法

    這篇文章主要介紹了Python 合并拼接字符串的方法,文中講解非常細致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • MacOS安裝python報錯"zsh:?command?not?found:python"的解決方法

    MacOS安裝python報錯"zsh:?command?not?found:python"的

    這篇文章主要給大家介紹了關(guān)于MacOS安裝python報錯"zsh:?command?not?found:python"的解決方法,文中將解決的辦法介紹的非常詳細,需要的朋友可以參考下
    2023-02-02
  • Python使用Socket實現(xiàn)簡單聊天程序

    Python使用Socket實現(xiàn)簡單聊天程序

    這篇文章主要介紹了Python使用Socket實現(xiàn)簡單聊天程序,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • 快速解決pyqt5窗體關(guān)閉后子線程不同時退出的問題

    快速解決pyqt5窗體關(guān)閉后子線程不同時退出的問題

    今天小編就為大家分享一篇快速解決pyqt5窗體關(guān)閉后子線程不同時退出的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-06-06

最新評論