de概述:引用計數(shù)器為主亭螟,標(biāo)記清除和分代回收為輔脱衙,+緩存機(jī)制七芭。
什么方式實現(xiàn)的呢 褂傀?是基于雙向鏈表锈麸。
1尿这、引用計數(shù)器
2撞羽、標(biāo)記清除
3认罩、分代回收
4稠歉、緩存機(jī)制
5掰担、Python的C源碼
環(huán)狀的雙向鏈表Refchain:狗鏈子。? ? refchain <--> lucky <-->?list等怒炸。在Python程序中創(chuàng)建的任何對象都會放在refchain雙向鏈表中带饱。例如:name="lucky";age=18;list1=[1, "a"];代碼執(zhí)行后會創(chuàng)建3個對象,都放到雙向鏈表中勺疼,也幫助我們維護(hù)了所有對象教寂,得到這個雙向鏈表相當(dāng)于得到了Python的所有對象。
創(chuàng)建的不同類型的對象执庐,在放在雙向鏈表也會有所不同酪耕。不同的例如值和類型,均包括:上一個對象的指針next轨淌,下一個對象的指針prev迂烁,類型ob_type,值递鹉,引用個數(shù)ob_refcnt(默認(rèn)1次)盟步。當(dāng)新增name2 = "lucky"。此時引用計數(shù)器+1 =2次躏结。多個元素組成的對象例如:列表的話:存儲--items:元素却盘,元素的個數(shù): ob_size。
各數(shù)據(jù)類型內(nèi)部結(jié)構(gòu)體都封裝了哪些值媳拴?例如:float
1黄橘、float:data=3.14 =>?上一個:next,下一個:prev,??ob_type=float,? ?ob_refcnt=1,? ob_fval:3.14。
引用計數(shù)器:
v1=3.14; v2=999; v3=(1,2,3);
當(dāng)Python程序在運(yùn)行時屈溉,會根據(jù)數(shù)據(jù)類型的不同找到其對應(yīng)的結(jié)構(gòu)體塞关,根據(jù)結(jié)構(gòu)體中的字段進(jìn)行創(chuàng)建相應(yīng)的數(shù)據(jù),然后將對象添加到refchain雙向鏈表中语婴。在源碼中有兩個關(guān)鍵的結(jié)構(gòu)體:pyobject(公共的那4個描孟,每個對象都有)和PyVarObject(多個元素組成的對象)。每個對象都含有ob_refcnt就是引用計數(shù)器砰左。當(dāng)其他變量引用對象時匿醒,引用計數(shù)器就會發(fā)生變化。a=111;b=a;此時引用次數(shù)=2;?刪除則減1缠导。
a = 111;b=a; del b =>刪除b變量廉羔,b對應(yīng)對象引用計數(shù)器減1;如果繼續(xù)del a?則表示刪除a變量,引用計數(shù)減1僻造。此時引用計數(shù)為0憋他;當(dāng)引用計數(shù)器為0時,意味著沒人在使用這個對象了髓削,這個對象是垃圾竹挡,系統(tǒng)會默認(rèn)垃圾回收。發(fā)生了兩件事:對象從refchain鏈表中移除立膛;將對象銷毀內(nèi)存歸還揪罕。(大體如此梯码,還缺乏緩存機(jī)制)。引用次數(shù)=變量賦值次數(shù)好啰。