1、每一個(gè)變量定義時(shí)都保存在一個(gè)叫zval的容器里面,這里面包含了數(shù)量的類型和和值,還包含了一個(gè)refcount(理解為存在幾個(gè)變量個(gè)數(shù))和is_ref(理解為是否為引用變量)兩個(gè)額外信息,當(dāng)變量被引用一次refcount就會+1,當(dāng)你unset一下之后這個(gè)值就會減1直到為0就會從內(nèi)存中刪除
2、定義一個(gè)變量的時(shí)候并不是每次都會擴(kuò)大預(yù)定于值,因?yàn)镻HP會在內(nèi)存中先預(yù)占用一個(gè)空間,等你聲明變量的時(shí)候就會分配給你,但是當(dāng)你超出這個(gè)預(yù)占用空間之后,那么它就會增加空間,但是等你刪除變量時(shí)候這個(gè)空間容量不會立即消失
3、變量的引用不會單獨(dú)的多增加內(nèi)存占用,它會指向zval結(jié)構(gòu)體,只是refcount+1
4、簡單說說,PHP的變量依賴于一個(gè)內(nèi)部實(shí)現(xiàn) symbol_table 符號表,而符號表的基礎(chǔ)實(shí)現(xiàn)是 HashTable ,也就是和PHP數(shù)組的基礎(chǔ)實(shí)現(xiàn)是一致的。真是因?yàn)榉柋淼拇嬖冢屛覀兛梢允褂胓lobal標(biāo)記全局變量,用如compact等函數(shù)直接從當(dāng)前符號表中拉出變量出來。
那在談?wù)勵}主說的unset($a)會不會馬上釋放空間,答案是否定的,unset支持從符號表中把名字為a的這個(gè)元素刪掉了(只是標(biāo)記這塊空間又可用了,而不是釋放空間)。
再說循環(huán)中重復(fù)更新$key這種情況,因?yàn)楦碌氖窍嗤值淖兞浚栽诜柋碇兴麄兪峭粋€(gè)元素,更新時(shí)就會更新相同的位置,之前元素的值就馬上被覆蓋了。
再說說申明了新的變量內(nèi)存就會增加這個(gè)問題,答案是不確定。這是符號表基于 HashTable 實(shí)現(xiàn)的特性所致, HashTable 并不是增加一個(gè)元素就申請一個(gè)元素的內(nèi)存,而是一次申請多個(gè)元素的內(nèi)存(只是這些位置標(biāo)記是未使用),而當(dāng) HashTable 被塞滿時(shí),再去申請新的多個(gè)元素的內(nèi)存。也就是說,當(dāng)我們申明或者賦值一個(gè)變量時(shí),如果它不在符號表中,PHP會將它加入到符號表里,而如果這時(shí)候符號表沒滿,那會采用符號表中已申請而未使用的內(nèi)存,如果符號表剛好的滿的,則會申請新的內(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ī)制講解