1.何為引用
id()方法:
id(obj, /)
? ? Return the identity of an object.
?????返回一個(gè)對(duì)象的標(biāo)識(shí)(地址)
? ? This is guaranteed to be unique among simultaneously existing objects.
? ? (CPython uses the object's memory address.)
代碼:
a = 1
b = 1
print(id(a))
print(id(b))?
print(a is b)
運(yùn)行結(jié)果:
1410343632
1410343632
True
緩沖區(qū):Python中對(duì)比較小的對(duì)象進(jìn)行了緩存定页,在使用的時(shí)候會(huì)首先到緩沖池中查詢漏麦,
如果有,就不再去開(kāi)辟內(nèi)存空間磨澡,對(duì)于int類型的數(shù)據(jù),這個(gè)范圍是-5~256
代碼:
a = 1000
b = 1000
print(a is b)
問(wèn)題:在cmd中執(zhí)行結(jié)果為False留特,在pycharm中執(zhí)行結(jié)果為True
原因:在cmd中編寫代碼军洼,是交互式執(zhí)行的锤窑,每一段代碼都作為一個(gè)獨(dú)立的代碼塊关面,而在編譯器或記事本中
(存儲(chǔ)為.py形式的)坦袍,是腳本式執(zhí)行的,一個(gè)文件作為一個(gè)代碼塊等太,在運(yùn)行的時(shí)候捂齐,如果發(fā)現(xiàn)這個(gè)代碼塊中已經(jīng)為這個(gè)對(duì)象
開(kāi)辟過(guò)內(nèi)存空間,就會(huì)直接引用它缩抡,而不會(huì)重新開(kāi)辟內(nèi)存空間
2.引用計(jì)數(shù)機(jī)制
引用計(jì)數(shù):一個(gè)對(duì)象身上的引用數(shù)目
當(dāng)一個(gè)對(duì)象的引用計(jì)數(shù)為0的時(shí)候奠宜,證明沒(méi)有其他對(duì)象引用它,這時(shí)候就可以釋放掉它占用的內(nèi)存空間
,完成垃圾回收压真。
代碼1:
from sys import getrefcount
a = 10
b = 10
print(id(a))
print(id(b))
print(getrefcount(a))#打印a的引用計(jì)數(shù)
print(getrefcount(b))#打印b的引用計(jì)數(shù)
運(yùn)行結(jié)果:
590126862000
590126862000
5
5
代碼2:
from sys import getrefcount
print("函數(shù)執(zhí)行前引用計(jì)數(shù):{}".format(getrefcount(1000)))
def test():
? ? a = 1000
? ? print("函數(shù)中引用計(jì)數(shù):{}".format(getrefcount(1000)))
print("函數(shù)執(zhí)行后引用計(jì)數(shù):{}".format(getrefcount(1000)))
test()
運(yùn)行結(jié)果:
函數(shù)執(zhí)行前引用計(jì)數(shù):3
函數(shù)執(zhí)行后引用計(jì)數(shù):3
函數(shù)中引用計(jì)數(shù):4
優(yōu)點(diǎn):實(shí)時(shí)性娩嚼,當(dāng)沒(méi)有人引用這個(gè)對(duì)象的時(shí)候,就會(huì)立即釋放掉它占用的內(nèi)存
缺點(diǎn):循環(huán)引用
循環(huán)引用
代碼:
a = []
b = []
a.append(b)
b.append(a)
print(a)
print(b)
運(yùn)行結(jié)果:
[[[...]]]
[[[...]]]
問(wèn)題:如果兩個(gè)對(duì)象相互引用的話榴都,那么即使沒(méi)有外部對(duì)象引用他們待锈,他們的引用計(jì)數(shù)也不為0漠其,這就造成了
永遠(yuǎn)也無(wú)法釋放他們所占空間嘴高,幾乎等同于內(nèi)存泄漏。
3.標(biāo)記-清除
標(biāo)記 - 清除:
為了解決循環(huán)引用的問(wèn)題和屎,python采用了標(biāo)記-清除的垃圾回收機(jī)制拴驮,當(dāng)兩個(gè)對(duì)象引用計(jì)數(shù)都為1,但是他們之間
只存在相互的引用柴信,這時(shí)候我們就認(rèn)為這兩個(gè)對(duì)象沒(méi)有被外部對(duì)象引用套啤,可以將他們占用的內(nèi)存空間釋放
過(guò)程:如果A,B相互引用随常,那么從A的角度來(lái)看潜沦,他有一個(gè)對(duì)B的引用,所以將B的引用計(jì)數(shù)-1绪氛,反過(guò)來(lái)唆鸡,B有一個(gè)對(duì)A的引用
所以A的引用也-1。
優(yōu)點(diǎn):
可以解決循環(huán)引用的問(wèn)題
問(wèn)題:
如果A對(duì)B有一個(gè)引用枣察,但是B對(duì)A沒(méi)有引用争占,這時(shí)候采用標(biāo)記-清除機(jī)制,A和B的引用計(jì)數(shù)都-1序目,A可以正潮酆郏回收內(nèi)存
但是,B?會(huì)因此有一個(gè)懸空引用猿涨。
循環(huán)垃圾回收器:
垃圾回收機(jī)制中專門負(fù)責(zé)確保釋放循環(huán)引用對(duì)象握童。
4.內(nèi)存結(jié)構(gòu)
?內(nèi)存池:
用戶管理小塊內(nèi)存的申請(qǐng)和釋放
小塊內(nèi)存:小于256b
小塊內(nèi)存申請(qǐng)時(shí),PyMem_Malloc直接在內(nèi)存池中申請(qǐng)內(nèi)存
大于256b時(shí)叛赚,會(huì)調(diào)用malloc方法