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