理解php核心的 引用計數器與寫時複製
阿新 • • 發佈:2019-01-08
zval結構中有以下兩個成員變數用於引用計數器:
改變$a的值時,發現refcount的值變回1,所有這時候變數$a和$b 指向不同的記憶體塊,這就是寫時複製。就是兩個指向同一記憶體塊的變數,當其中一個變數的發生變化,才會另外建立一個記憶體塊去儲存新的值。
寫時複製也是一種引用,只不過這種引用會受到變數值的改變而破壞罷了。
顯式引用情況:
執行結果:
在PHP核心中通過以下程式碼判斷是否複製變數:
is_ref:BOOL值,標識變數是否是引用集合寫時複製:就是當變數的值改變時才進行記憶體的複製。
refcount:計算指向引用集合的變數個數
<?php
$a = "this a test ";
xdebug_debug_zval('a');
$b = $a;
xdebug_debug_zval('a');
$a = "changed the test value";
xdebug_debug_zval('a');
a:
(refcount=1, is_ref=0), (length=12) a:
(refcount=2, is_ref=0), (length=12) a:
(refcount=1, is_ref=0)當$a的值賦給變數$b時,變數$a的refcount增加1,所以這時候變數$a跟變數$b是指向同一記憶體塊的;, (length=22)
改變$a的值時,發現refcount的值變回1,所有這時候變數$a和$b 指向不同的記憶體塊,這就是寫時複製。就是兩個指向同一記憶體塊的變數,當其中一個變數的發生變化,才會另外建立一個記憶體塊去儲存新的值。
寫時複製也是一種引用,只不過這種引用會受到變數值的改變而破壞罷了。
顯式引用情況:
<?php
$a = 1;
xdebug_debug_zval('a');
$b = & $a;
xdebug_debug_zval('a');
$b += 5;
xdebug_debug_zval('a');
a:
(refcount=1, is_ref=0), a:
(refcount=2, is_ref=1), a:
(refcount=2, is_ref=1),is_ref欄位等於1,表示此變數被引用。refcount也相應+1
在PHP核心中通過以下程式碼判斷是否複製變數:
if ((*varval->is_ref || (*varval)->refcount<2)) {
return *varval;
}