變量的實(shí)現(xiàn)
新縣網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián)公司,新縣網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為新縣千余家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站制作要多少錢,請找那個售后服務(wù)好的新縣做網(wǎng)站的公司定做!
PHP 的變量是弱類型的,可以表示整數(shù)、浮點(diǎn)數(shù)、字符串等類型。PHP 的變量是使用結(jié)構(gòu)體 zval 表示的
PHP 5.* zval 和 zend_value 結(jié)構(gòu)
struct _zval_struct { // 結(jié)構(gòu)體 zvalue_value value; zend_uint refcount__gc; zend_uchar type; zend_uchar is_ref__gc; } typedef union _zvalue_value { // 聯(lián)合體 long lval; double dval; struct { char *val; int len; } str; // 字符串 HashTable *ht; // 數(shù)組 zend_object_value obj; // 對象 zend_ast *ast; } zvalue_value;
PHP 7.0 zval 和 zend_value 結(jié)構(gòu)
struct _zval_struct { union { zend_long lval; /* long value */ double dval; /* double value */ zend_refcounted *counted; zend_string *str; zend_array *arr; zend_object *obj; zend_resource *res; zend_reference *ref; zend_ast_ref *ast; zval *zv; void *ptr; zend_class_entry *ce; zend_function *func; struct { uint32_t w1; uint32_t w2; } ww; } value; union { struct { ZEND_ENDIAN_LOHI_4( zend_uchar type, /* active type */ zend_uchar type_flags, zend_uchar const_flags, zend_uchar reserved) /* call info for EX(This) */ } v; uint32_t type_info; } u1; union { uint32_t var_flags; uint32_t next; /* hash collision chain */ uint32_t cache_slot; /* literal cache slot */ uint32_t lineno; /* line number (for ast nodes) */ uint32_t num_args; /* arguments number for EX(This) */ uint32_t fe_pos; /* foreach position */ uint32_t fe_iter_idx; /* foreach iterator index */ } u2; };
PHP5 與 PHP7 引用計(jì)數(shù)的對比
php 5.* 變量賦值等操作引用計(jì)數(shù)如圖所示,在倒數(shù)第二步,會形成一個循環(huán)引用,并且在 unset 操作之后,會產(chǎn)生垃圾。
PHP 7 的計(jì)數(shù)放到了具體的 value 中,zval 不存在寫時復(fù)制(寫時分離)。
并且 PHP 7 的有一個專門的 zend_reference 用來表示引用。
有了以上關(guān)于 PHP 變量存儲的知識,我們可以理解一下 PHP 是如何做垃圾回收的了。
什么是垃圾
首先,我們需要定義什么是垃圾。
1. refcount 增加的不是
2. refcount 等于0的不是,這個會被直接清除
3. refcount 減少,并且不等于0的才是垃圾
垃圾收集
1. php7 要求數(shù)據(jù)類型是數(shù)組和對象,并且 type_flag 是 IS_TYPE_COLLECTABLE
2. 沒有在緩沖區(qū)中存在過
3. 沒有被標(biāo)記過
4. 標(biāo)記為紫色,并且放到緩沖區(qū)中
PHP 5.3 版本以及之后的版本
1. 將垃圾放到一個 root 池中
2. 當(dāng)滿 10000 個節(jié)點(diǎn)的時候進(jìn)行垃圾回收
3. 遍歷雙向鏈表中的節(jié)點(diǎn) refcount-1
4. 遍歷雙向鏈表將 refcount=0 的節(jié)點(diǎn)刪除,到free隊(duì)列中
5. 對 refcount!=0 的 refcount+1
以上就是PHP是如何做垃圾回收的(圖文)的詳細(xì)內(nèi)容,更多請關(guān)注創(chuàng)新互聯(lián)其它相關(guān)文章!