PHP使用Copy-on write和引用計數來管理記憶體。
Copy-on-write又是簡寫為COW(寫入時複製),是電腦編程中的一種最佳化策略。Copy-on-write在PHP中,可以認為多個變數都使用資訊的同一份拷貝,也就是說這些變數都指向同一個記憶體位址。由於只是讀取這些變數。沒有必要為每個變數在記憶體中拷貝一份相同的值,這就節省了很多記憶體資源。但是當一個變數需要修改值的時候,將真正的對象複製到新的記憶體位址中,並修改新對象的記憶體映射表指向這個新的位置,並在新的記憶體位置上執行寫操作。
如下面的代碼:
<?php$a=array(1,4,5);$b=$a;//數組並未被複製$a[1]=10;//數組複製了,並且修改了值print_r($a);print_r($b);?>
運行完畢後$a和$b的值是不相同的。
$a是1,10,5
$b是1,4,5
這有點類似C#中實值型別的賦值。要使得$a和$b始終是同一份引用,則代碼寫為:
$b=&$a;
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釋放掉。
本文出自 “一隻部落格” 部落格,請務必保留此出處http://cnn237111.blog.51cto.com/2359144/1281534