天天看點

PHP語言中的垃圾回收機制

php使用copy-on write和引用計數來管理記憶體。

copy-on-write又是簡寫為cow(寫入時複制),是計算機程式設計中的一種優化政策。copy-on-write在php中,可以認為多個變量都使用資訊的同一份拷貝,也就是說這些變量都指向同一個記憶體位址。由于隻是讀取這些變量。沒有必要為每個變量在記憶體中拷貝一份相同的值,這就節省了很多記憶體資源。但是當一個變量需要修改值的時候,将真正的對象複制到新的記憶體位址中,并修改新對象的記憶體映射表指向這個新的位置,并在新的記憶體位置上執行寫操作。

如下面的代碼:

運作完畢後$a和$b的值是不相同的。

$a是1,10,5

$b是1,4,5

這有點類似c#中值類型的指派。要使得$a和$b始終是同一份引用,則代碼寫為:

php中和copy-on-write技術搭配的一個術語叫引用計數(reference count)。

在php中每一個變量都有2部分組成,一個是變量名,還有就是變量的值,他們存放在一個稱為符号表的結構中,這個符号表是一個數組,它映射了變量名和值在記憶體中的位置。符号表中每一個值都有一個所謂的引用計數,記錄了有多少種方法能夠獲得這個值,即有多少個變量名指向這個值。

如上面的代碼當$a初始化後,$b=$a後,這個數組就有一個引用計數2(如果你通過c的api方法去檢視引用計數,這個值實際上是3,但從使用者角度來看,解釋成2更好了解)。也就是說,這個記憶體中的值可以有2種方法獲得,通過$a和$b.然後當$a[1]的值改變之後,則php為$a建立了一個新的記憶體空間,也就是出現2個數組了。這兩個數組的引用計數都為1。當一個變量走出了作用域範圍,比如函數中的本地變量,這個變量在函數運作完後就失效了,那麼之前這個變量指向的值的引用計數就會減1。同樣的,如果一個變量指向一個新的記憶體位址,那麼這個老的位址的值上的引用計數也會減1。當一個記憶體空間的引用計數為0的時候,就會被php釋放掉。