In-depth analysis of PHP reference counting mechanism _ PHP Tutorial

Source: Internet
Author: User
Deeply parse the reference counting mechanism of PHP. After the PHP variable is declared and assigned a value, the variable name exists in the symbol table, and the value and class information exist in zval. zval contains four variables: is_ref, refcount, value, type, the zval source code is as follows: Copy the PHP variable declaration and assign values. the variable name exists in the symbol table, and the value and class information exist in zval. zval contains four variables, Is_ref, refcount, value, type, zvalThe source code is as follows:

The code is as follows:


Struct _ zval_struct {
/* Variable information */
Zvalue_value value;/* value */
Zend_uint refcount _ gc;
Zend_uchar type;/* active type */
Zend_uchar is_ref _ gc;
};


Refcount indicates the total number of zval with the same value address. when refcount is set to 0, zval is destroyed.
Is_ref indicates whether a zval is referenced. There are two statuses: "0" and "1 ".

Here, we will analyze when zval will be copied or new memory space will be opened.
1. when is_ref = 0 and refcount> 1, if you change the value of a variable pointing to this zval, a new zval, the original zval refcount -- is generated, for example: $ a = 1; $ B = $ a; $ B = 2; zval will be copied, that is, the original AB points to the same zval, and then B will use the newly created zval

2. when is_ref = 0 and refcount> 1, if zval is assigned to a reference variable, the original zval is used to assign values to the variable and to the variable to be assigned, other variables pointing to the original zval point to a newly copied zval, and the refcount is recalculated, for example, $ a = 1; $ B = $; $ c = $ a; $ d = & $ a; in this case, ad uses the original zval and bc uses the newly copied zval.

3. when is_ref = 1 and refcount> 1, if zval is copied to a non-referenced variable, a newly copied zval will be used for this non-referenced variable, and the refcount of zval will not change, for example: $ a = 1; $ B = & $ a; $ c = $ a, AB uses the original zval, and c uses the newly copied zval.
Type indicates the zval value type. the macro definition is as follows:

The code is as follows:


# Define IS_NULL 0
# Define IS_LONG 1
# Define IS_DOUBLE 2
# Define IS_BOOL 3
# Define IS_ARRAY 4
# Define IS_OBJECT 5
# Define IS_STRING 6
# Define IS_RESOURCE 7
# Define IS_CONSTANT 8
# Define IS_CONSTANT_ARRAY 9


Value indicates the zval value. it is also a community and the code is as follows:

The code is as follows:


Typedef union _ zvalue_value {
Long lval;/* long value */
Double dval;/* double value */
Struct {
Char * val;
Int len;
} Str;
HashTable * ht;/* hash table value */
Zend_object_value obj;
} Zvalue_value;


Now you know how php changes the type, because its value is actually a struct that can represent any type, the specific value depends on the type to determine which variable in the community to store the value.

See example 1 below.

The code is as follows:


.-----------
$ A = 1;
$ B = $;
$ C = $;
.-----------
$ D = & $;
.-----------
$ A = 2;
.-----------
$ B = null;


View refcount, is_ref, and zval changes
After the first part is executed, check the output.
1 -----------------------------
A :( refcount = 3, is_ref = 0), int 1
B :( refcount = 3, is_ref = 0), int 1
C :( refcount = 3, is_ref = 0), int 1
We can see that a, B, and c use the same zval.
Then, let's look at
2 ----------------------------
A :( refcount = 2, is_ref = 1), int 1
B :( refcount = 2, is_ref = 0), int 1
C :( refcount = 2, is_ref = 0), int 1
D :( refcount = 2, is_ref = 1), int 1
Note that at this time a and d are together, they use the same zval, while bc uses a newly generated zval and recalculates the refcount and is_ref of the two zval.
3 ----------------------------
A :( refcount = 2, is_ref = 1), int 2
B :( refcount = 2, is_ref = 0), int 1
C :( refcount = 2, is_ref = 0), int 1
D :( refcount = 2, is_ref = 1), int 2
We can know that the values of the two is_ref = 1 Friends of ad are changed at the same time.
4 ----------------------------
A :( refcount = 2, is_ref = 1), int 2
B :( refcount = 1, is_ref = 0), null
C :( refcount = 1, is_ref = 0), int 1
D :( refcount = 2, is_ref = 1), int 2
Bc because their zval is_ref = 0, so they are not good friends, their values will not change at the same time, so bc's zval split again, B = null c = 1

Struct, is_ref, refcount, value, type, zval source code is as follows...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.