您好,登錄后才能下訂單哦!
變量的實現
PHP 的變量是弱類型的,可以表示整數、浮點數、字符串等類型。PHP 的變量是使用結構體 zval 表示的
PHP 5.* zval 和 zend_value 結構
struct _zval_struct { // 結構體 zvalue_value value; zend_uint refcount__gc; zend_uchar type; zend_uchar is_ref__gc; } typedef union _zvalue_value { // 聯合體 long lval; double dval; struct { char *val; int len; } str; // 字符串 HashTable *ht; // 數組 zend_object_value obj; // 對象 zend_ast *ast; } zvalue_value;
PHP 7.0 zval 和 zend_value 結構
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 引用計數的對比
php 5.* 變量賦值等操作引用計數如圖所示,在倒數第二步,會形成一個循環引用,并且在 unset 操作之后,會產生垃圾。
PHP 7 的計數放到了具體的 value 中,zval 不存在寫時復制(寫時分離)。
并且 PHP 7 的有一個專門的 zend_reference 用來表示引用。
有了以上關于 PHP 變量存儲的知識,我們可以理解一下 PHP 是如何做垃圾回收的了。
什么是垃圾
首先,我們需要定義什么是垃圾。
1. refcount 增加的不是
2. refcount 等于0的不是,這個會被直接清除
3. refcount 減少,并且不等于0的才是垃圾
垃圾收集
1. php7 要求數據類型是數組和對象,并且 type_flag 是 IS_TYPE_COLLECTABLE
2. 沒有在緩沖區中存在過
3. 沒有被標記過
4. 標記為紫色,并且放到緩沖區中
PHP 5.3 版本以及之后的版本
1. 將垃圾放到一個 root 池中
2. 當滿 10000 個節點的時候進行垃圾回收
3. 遍歷雙向鏈表中的節點 refcount-1
4. 遍歷雙向鏈表將 refcount=0 的節點刪除,到free隊列中
5. 對 refcount!=0 的 refcount+1
以上就是PHP是如何做垃圾回收的(圖文)的詳細內容,更多請關注億速云其它相關文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。