1、每一個(gè)變量定義時(shí)都保存在一個(gè)叫zval的容器里面,這里面包含了數(shù)量的類型和和值,還包含了一個(gè)refcount(理解為存在幾個(gè)變量個(gè)數(shù))和is_ref(理解為是否為引用變量)兩個(gè)額外信息,當(dāng)變量被引用一次refcount就會(huì)+1,當(dāng)你unset一下之后這個(gè)值就會(huì)減1直到為0就會(huì)從內(nèi)存中刪除
2、定義一個(gè)變量的時(shí)候并不是每次都會(huì)擴(kuò)大預(yù)定于值,因?yàn)镻HP會(huì)在內(nèi)存中先預(yù)占用一個(gè)空間,等你聲明變量的時(shí)候就會(huì)分配給你,但是當(dāng)你超出這個(gè)預(yù)占用空間之后,那么它就會(huì)增加空間,但是等你刪除變量時(shí)候這個(gè)空間容量不會(huì)立即消失
3、變量的引用不會(huì)單獨(dú)的多增加內(nèi)存占用,它會(huì)指向zval結(jié)構(gòu)體,只是refcount+1
4、簡單說說,PHP的變量依賴于一個(gè)內(nèi)部實(shí)現(xiàn) symbol_table 符號(hào)表,而符號(hào)表的基礎(chǔ)實(shí)現(xiàn)是 HashTable ,也就是和PHP數(shù)組的基礎(chǔ)實(shí)現(xiàn)是一致的。真是因?yàn)榉?hào)表的存在,讓我們可以使用global標(biāo)記全局變量,用如compact等函數(shù)直接從當(dāng)前符號(hào)表中拉出變量出來。
那在談?wù)勵(lì)}主說的unset($a)會(huì)不會(huì)馬上釋放空間,答案是否定的,unset支持從符號(hào)表中把名字為a的這個(gè)元素刪掉了(只是標(biāo)記這塊空間又可用了,而不是釋放空間)。
再說循環(huán)中重復(fù)更新$key這種情況,因?yàn)楦碌氖窍嗤值淖兞?,所以在符?hào)表中他們是同一個(gè)元素,更新時(shí)就會(huì)更新相同的位置,之前元素的值就馬上被覆蓋了。
再說說申明了新的變量內(nèi)存就會(huì)增加這個(gè)問題,答案是不確定。這是符號(hào)表基于 HashTable 實(shí)現(xiàn)的特性所致, HashTable 并不是增加一個(gè)元素就申請(qǐng)一個(gè)元素的內(nèi)存,而是一次申請(qǐng)多個(gè)元素的內(nèi)存(只是這些位置標(biāo)記是未使用),而當(dāng) HashTable 被塞滿時(shí),再去申請(qǐng)新的多個(gè)元素的內(nèi)存。也就是說,當(dāng)我們申明或者賦值一個(gè)變量時(shí),如果它不在符號(hào)表中,PHP會(huì)將它加入到符號(hào)表里,而如果這時(shí)候符號(hào)表沒滿,那會(huì)采用符號(hào)表中已申請(qǐng)而未使用的內(nèi)存,如果符號(hào)表剛好的滿的,則會(huì)申請(qǐng)新的內(nèi)存出來存放,而新的內(nèi)存不僅僅只有這個(gè)變量需要的內(nèi)存這么小
您可能感興趣的文章:- PHP的垃圾回收機(jī)制代碼實(shí)例講解
- PHP進(jìn)階學(xué)習(xí)之垃圾回收機(jī)制詳解
- PHP析構(gòu)函數(shù)destruct與垃圾回收機(jī)制的講解
- 解讀PHP中的垃圾回收機(jī)制
- PHP垃圾回收機(jī)制講解