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