PHP7引用型別

2022-08-23 19:21:10 字數 1307 閱讀 9149

php5在引入引用計數後,使用了refcount_gc來記錄次數,同時使用is_ref_gc來記錄是否是引用型別。

例如$a = 'hello';

//$a->zval1(type=is_string,refcount_gc=1,is_ref_gc=0)

這個時候$a指向乙個結構體,主要看refcount_gc=1,這就是引用計數字段,因為hello這個字串被賦值給了$a,所以這個時候hello的引用計數就是1

$b = $a;

$b,$a->zval1(type=is_string,refcount_gc=2,is_ref_gc=0)

這個時候又把$a賦值給了$b,所以這個時候$b和$a同時指向這個結構體,並且引用計數加1

$c = &$b;

//$a->zval1(type=is_string,refcount_gc=1,is_ref_gc=0)

//$c,$b->zval2(type=is_string,refcount_gc=2,is_ref_gc=1)

這個時候因為把$b賦值給了$c,但是是傳址的方式,所以在這個時候就要分離了,$a還指向原來的結構體,$c和$b同時指向乙個新的結構體,這個時候zval的is_ref_gc值會改變,使得此時的zval必須進行分離,但是實際上他們的值還沒有變化,這使得需要在堆中維護兩個值為"hello"的zval。

下面我們來看看php7中的實現

php7引入了新的型別is_reference來處理這個問題,首先看看zend_reference的結構體:

struct _zend_reference{

zend_refcounted_h gc;

zval val;

$a = 'hello';

//$a->zend_string(refcount=1,val)

$b = $a;

//$b,$a->zend_string(refcount=2,val)

$c = &$b;

//$a->zend_string(refcount=2,val)

//$c,$b->zval(type=is_reference,refcount=2)->zend_string(refcount=2,val)

從上面可以看出來,當使用&操作時,會建立一種新的中間結構體zend_referenct,這個結構體會指向真正的zend_string結構體,所以zend_string結構體的引用計數不變,同時zend_reference結構體的引用計數變為2,因為$c和$b此時的型別都會變為zend_reference,這樣的好處是原始的zend_string在記憶體中始終只有乙份(避免了由於字串的重複申請導致的記憶體浪費),更加易於維護。

php7 引用成為一種型別

a abc is ref 0 ref count 1 b a is ref 0 ref count 2 c a is ref 1 ref count 2 即a c 共用乙個zval,b單獨用乙個zval 當然 ref count為1 c 2 a range 10000 b a count a1 相當...

5 0 引用型別

ecmascript中有5中簡單資料型別 也叫基本資料型別 undefined boolean null number string。還有一種複雜資料型別 object object本質上是一組無序的明值対組成的 1 應用型別的值 物件 是引用型別的乙個例項。2 在es種,引用型別是一種資料結構,用...

6 引用型別 Object

1 例項化物件var obj new object var obj2 給物件設定屬性 obj2.name lc obj2.女 obj2.age 23 obj2 birthday 1994 03 13 obj2.say function 訪問物件的屬性或方法 console.log obj2.name...