php用引用計算和寫時複製(copy-on-write)來管理記憶體。寫時複製確保在變數之間複製值時不浪費記憶體,引用計算確保在引用不再需要時將記憶體返回給作業系統。
要理解PHP中的記憶體管理,必須首先理解符號表(symbol table)的思想,變數有兩部分–變數名(如$name)和變數值(如”Fred”)。符號表是一個數組,此數組將變數名映射到其值在記憶體中的位置。
當從一個變數複製值到另一個變數是,PHP沒有因為複製值而得到更多的記憶體,而是更新符號表,以表明“這兩個變數是同一塊記憶體的名字”。所以下面的代碼實際上並沒有建立一個新數組:
$worker = array(“Fred”,35,”Wilma”);
$other = $worker; //數組沒有被複製
如果修改任意一個拷貝,那麼PHP將分配記憶體併產生該拷貝:
$worker[1] = 36; //數組被複製,值發生變化
由於延遲分配和複製,PHP在很多情況下節省了時間和記憶體。這就是寫時複製。
符號表指向的每個值都有一個引用計數(reference count),它是一個數字,表示通向那片記憶體的途徑數。在將數組的初值賦給$worker和將$worker賦給$other後,符號表中指向數組的條 目為$worker和$other,引用計數為2。換句話說,有兩條途徑可以到達那片記憶體:通過$worker或$other。但$worker[1]改 變以後,PHP為$worker建立一個新數組,並且每一個數組的引用計數都僅僅為1。
當一個變數不在範圍中(函數參數或局部變數在函數的結尾)時,引用計數值減1。當一個變數被分配的值在記憶體的其他地區時,舊的引用計數值減1。當引用計數值達到0時,記憶體被釋放。這就是引用計數。
引用計數式管理記憶體的首選方法,保持變數的函數局部性傳遞函數需要用到的值,並且讓引用計數負責在引用不再需要時釋放記憶體。如果想要獲得更多資訊或完全控制釋放變數的值,可以用函數isset()和unset()。
查看變數是否已經設定(即使是Null 字元串),用isset():
$s1 = isset($name); //$s1為false
$name = "Fred";
$s2 = isset($name); //$s2為true
用unset()來刪除一個變數的值:
$name = "Fred";
unset($name); //$name為NULL