摘要:而采用的是引用計數(shù)機制為主,標記清理和分代收集兩種機制為輔的策略。現(xiàn)在我們先去考慮一下,什么情況下引用計數(shù),什么情況下,當引用次數(shù)為時,肯定就是需要進行回收的時刻。引用計數(shù)機制缺點維護引用計數(shù)需要消耗一定的資源循環(huán)應用時,無法回收。
上一篇文章:私有化規(guī)則與屬性Property
下一篇文章:Python進程專題總覽篇
高級語言一般都有垃圾回收機制,其中c、c++使用的是用戶自己管維護內(nèi)存的方式,這種方式比較自由,但如果回收不當也會引起垃內(nèi)存泄露等問題。而python采用的是引用計數(shù)機制為主,標記-清理和分代收集兩種機制為輔的策略。
1、引用計數(shù)python中一切皆對象,所以python底層計數(shù)結(jié)構(gòu)地就可以抽象為:
引用計數(shù)結(jié)構(gòu)體{ 引用計數(shù); 引用的對象 }
是不是簡單明了。現(xiàn)在我們先去考慮一下,什么情況下引用計數(shù)+1,什么情況下-1,當引用次數(shù)為0時,肯定就是需要進行回收的時刻。
1、對象被創(chuàng)建時,例如 mark="帥哥" 2、對象被copy引用時,例如 mark2=mark,此時mark引用計數(shù)+1 3、對象被作為參數(shù),傳入到一個函數(shù)中時 4、對象作為一個子元素,存儲到容器中時,例如 list=[mark,mark2]
1、對象別名被顯示銷毀,例如 del mark 2、對象引用被賦予新的對象,例如mark2=mark3,此時mark引用計數(shù)-1(對照引用計數(shù)+1的情況下的第二點來看) 3、一個函數(shù)離開他的作用域,例如函數(shù)執(zhí)行完成,它的引用參數(shù)的引用計數(shù)-1 4、對象所在容器被銷毀,或者從容器中刪除。
實例:
import sys a = "mark 帥哥" print(sys.getrefcount(a))
結(jié)果:
4
備注:如果實際結(jié)果與上面不符,跟使用的編輯器有很大關(guān)系,重點是理解計數(shù)引用原理,不要太在意為啥不是1.
想理解原因可以轉(zhuǎn)看:https://stackoverflow.com/questions/45021901/why-does-a-newly-created-variable-in-python-have-a-ref-count-of-four
1、簡單、直觀 2、實時性,只要沒有了引用就釋放資源。
1、維護引用計數(shù)需要消耗一定的資源 2、循環(huán)應用時,無法回收。也正是因為這個原因,才需要通過標記-清理和分代收集機制來輔助引用計數(shù)機制。2、標記-清理
由上面內(nèi)容我們可以知道,引用計數(shù)機制有兩個缺點,缺點1還可以勉強讓人接受,缺點2如果不解決,肯定會引起內(nèi)存泄露,為了解決這個問題,引入了標記刪除。
我們先來看個實例,從實例中領(lǐng)會標記刪除:
a=[1,2]#假設(shè)此時a的引用為1 b=[3,4]#假設(shè)此時b的引用為1 #循環(huán)引用 a.append(b)#b的引用+1=2 b.append(a)//a的引用+1=2 假如現(xiàn)在需要刪除a,應該如何回收呢? c=[5,6]#假設(shè)此時c的引用為1 d=[7,8]#假設(shè)此時d的引用為1 #循環(huán)引用 c.append(d)#c的引用+1=2 d.append(c)#d的引用+1=2 假如現(xiàn)在需要同時刪除c、d,應該如何回收呢?
首先我們應該已經(jīng)知道,不管上面兩種情況的哪一個都無法只通過計數(shù)來完成回收,因為隨便刪除一個變量,它的引用只會-1,變成1,還是大于0,不會回收,為了解決這個問題,開始看標記刪除來大展神威吧。
puthon標記刪除時通過l兩個容器來完成的:死亡容器、存活容器。 首先,我們先來分析情況2,刪除c、d 刪除后,c的引用為1,d的引用為1,根據(jù)引用計數(shù),還無法刪除 標記刪除第一步:對執(zhí)行刪除操作后的每個引用-1,此時c的引用為0,d的引用為0,把他們都放到死亡容器內(nèi)。把那些引用仍然大于0的放到存活容器內(nèi)。 標記刪除第二步:遍歷存活容器,查看是否有的存活容器引用了死亡容器內(nèi)的對象,如果有就把該對象從死亡容器內(nèi)取出,放到存活容器內(nèi)。 由于c、d都沒有對象引用他們了,所以經(jīng)過這一步驟,他們還是在死亡組。 標記刪除第三部:將死亡組所有對象刪除。 這樣就完成了對從c、d的刪除。
同樣道理,我們來分析:只刪除a的過程:
標記刪除第一步:對執(zhí)行刪除(-1)后的每個引用-1,那么a的引用就是0,b的引用為1,將a放到死亡容器,將b放到存活容器。 標記刪除第二步:循環(huán)存活容器,發(fā)現(xiàn)b引用a,復活a:將a放到存活容器內(nèi)。 標記刪除第三步:刪除死亡容器內(nèi)的所有對象。
綜上所說,發(fā)現(xiàn)對于循環(huán)引用,必須將循環(huán)引用的雙發(fā)對象都刪除,才可以被回收。
標記-清理就是這么簡單,
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/42288.html
摘要:虛擬機棧區(qū)也就是通常所說的棧區(qū),它描述的是方法執(zhí)行的內(nèi)存模型,每個方法被執(zhí)行的時候都創(chuàng)建一個棧幀,用于存儲局部變量表操作數(shù)棧動態(tài)鏈接方法出口等。每個方法被調(diào)用到完成,相當于一個棧幀在虛擬機棧中從入棧到出棧的過程。 大多數(shù)情況下我們對GC的了解都只是淺層含義上的,下面我們來詳細講解下內(nèi)部的一些實現(xiàn)原理。講解GC之前,我們得先了解下JVM的內(nèi)存結(jié)構(gòu),才能讓我們理解GC導致是干嘛的。 一.J...
摘要:內(nèi)部通過引用計數(shù)機制來統(tǒng)計一個對象被引用的次數(shù)。下一步,就該被我們的垃圾回收器給收走了。而我們垃圾回收機制只有當引用計數(shù)為的時候才會釋放對象。以空間換時間的方法提高垃圾回收效率。 人生苦短,只談風月,談什么垃圾回收。據(jù)說上圖是某語言的垃圾回收機制。。。我們寫過C語言、C++的朋友都知道,我們的C語言是沒有垃圾回...
摘要:不是引用類型,無法輸出簡而言之,堆內(nèi)存存放引用值,棧內(nèi)存存放固定類型值。變量的查詢在變量的查詢中,訪問局部變量要比全局變量來得快,因此不需要向上搜索作用域鏈。 贊助我以寫出更好的文章,give me a cup of coffee? 2017最新最全前端面試題 基本類型值有:undefined,NUll,Boolean,Number和String,這些類型分別在內(nèi)存中占有固定的大小空...
摘要:不過不要緊,垃圾分類雖然要執(zhí)行,但是奶茶也可以照喝。這里我們考慮四個類別干垃圾,濕垃圾,有害垃圾還是可回收垃圾。報紙可回收垃圾電池有害垃圾一次性餐盒干垃圾我們對圖片里的物品進行分類,這是圖像處理和識別的領(lǐng)域。 showImg(https://segmentfault.com/img/remote/1460000019671613); 目錄0 環(huán)境1 引言2 思路 3 圖像分類 4 總結(jié)...
閱讀 3359·2023-04-26 00:07
閱讀 3989·2021-11-23 10:08
閱讀 2990·2021-11-22 09:34
閱讀 897·2021-09-22 15:27
閱讀 1784·2019-08-30 15:54
閱讀 3803·2019-08-30 14:07
閱讀 944·2019-08-30 11:12
閱讀 712·2019-08-29 18:44