PHP garbage collection mechanism-basic reference counting knowledge

Source: Internet
Author: User
PHP features-garbage collection mechanism-basic knowledge of reference counting each php variable is stored in a variable container called "zval. A zval variable container not only contains the type and value of the variable, but also contains two bytes of additional information. The first is "is_ref", which is a bool value to identify whether the variable belongs to the reference set ). With this byte, the php engine can distinguish between common variables and reference variables. because php allows users to use & to use custom references, the zval variable container also has an internal reference counting mechanism, to optimize memory usage. The second extra byte is "refcount", used to indicate the number of variables (also known as symbol) pointing to the zval variable container. All symbols exist in a symbol table. each symbol has a scope, and the primary scripts (for example, scripts requested by a browser) and each function or method have a scope.

When a variable is assigned a constant value, a zval variable container is generated, as shown in the following example:

Example #1 create a new zval container

 

In the preceding example, the new variable a is generated in the current scope. A variable container of the string type and the new string value is generated. In the additional two bytes, "is_ref" is set to FALSE by default because no custom reference is generated. "Refcount" is set to 1 because only one variable uses this variable container. note that when the value of "refcount" is 1, the value of "is_ref" is always FALSE. if you have installed Xdebug, you can call the xdebug_debug_zval () function to display the values of "refcount" and "is_ref.

Example #2 display zval information

 

The above routine will output:

a: (refcount=1, is_ref=0)='new string'

Assigning a variable to another variable will increase the number of references (refcount ).

Example #3 Growth of refcount in zval

 

The above routine will output:

a: (refcount=2, is_ref=0)='new string'

At this time, the number of references is 2, because the same variable container is associated with variable a and variable B. php does not copy the generated variable container when it is not necessary. The variable container is destroyed when "refcount" is changed to 0. when any variable associated with a variable container leaves its scope (for example, function execution ends), or the function unset () is called for the variable, "refcount" is reduced by 1, the following example shows how:

Example #4 reduce refcount in zval

 

The above routine will output:

a: (refcount=3, is_ref=0)='new string'a: (refcount=1, is_ref=0)='new string'

If we execute unset ($ a);, the variable container containing the type and value will be deleted from the memory.

Compound Types)

When considering a composite type like array and object, this is a little complicated. Unlike values of the scalar type, array and object variables store their members or attributes in their own symbol tables. This means that the following example will generate three zval variable containers.

Example #5 create an array zval

  'life', 'number' => 42 );    xdebug_debug_zval( 'a' );?>

The output of the preceding routine is similar:

a: (refcount=1, is_ref=0)=array (   'meaning' => (refcount=1, is_ref=0)='life',   'number' => (refcount=1, is_ref=0)=42)

Example #6 add an existing element to the array

  'life', 'number' => 42 );    $a['life'] = $a['meaning'];    xdebug_debug_zval( 'a' );?>

The output of the preceding routine is similar:

a: (refcount=1, is_ref=0)=array (   'meaning' => (refcount=2, is_ref=0)='life',   'number' => (refcount=1, is_ref=0)=42,   'life' => (refcount=2, is_ref=0)='life')

Or the graphical display is as follows:

From the above xdebug output information, we can see that the original array elements and newly added array elements are associated with the zval variable container of the same "refcount" 2. although the Xdebug output shows two zval variable containers with the value of 'life', they are actually the same. The xdebug_debug_zval () function does not display this information, but you can see it by displaying the memory pointer information.

Deleting an element in an array is similar to deleting a variable from the scope. after the element is deleted, the "refcount" value of the container in the array is reduced. Similarly, when "refcount" is 0, the variable container is deleted from the memory, another example is as follows:

Example #7 remove elements from an array

  'life', 'number' => 42 );    $a['life'] = $a['meaning'];    unset( $a['meaning'], $a['number'] );    xdebug_debug_zval( 'a' );?>

The output of the preceding routine is similar:

a: (refcount=1, is_ref=0)=array (   'life' => (refcount=1, is_ref=0)='life')

Now, when we add an array itself as an element of this array, things will become interesting. The next example will illustrate this. In this example, we add a reference operator. otherwise, php will generate a copy.

Example #8 add an array element to the array itself

 

The output of the preceding routine is similar:

a: (refcount=2, is_ref=1)=array (   0 => (refcount=1, is_ref=0)='one',   1 => (refcount=2, is_ref=1)=...)

Or graphically

The array variable (a) is also the second element of the array (1) pointing to the variable container "refcount" is 2. In the above output result, "..." indicates that a recursive operation has occurred. Obviously, this means that "..." points to the original array.

Just as before, calling unset for a variable will delete this symbol, and the number of references it points to in the variable container will also be reduced by 1. Therefore, if we call unset for variable $ a after executing the above code, the number of times that the variable $ a and the array element "1" point to the variable container will be reduced by 1, from "2" to "1 ". the following example shows how:

Example #9 destroy $

(refcount=1, is_ref=1)=array (   0 => (refcount=1, is_ref=0)='one',   1 => (refcount=1, is_ref=1)=...)

Or the graphical display is as follows:

Cleanup Problems)

Although no symbols in a specific scope point to this structure (that is, the variable container), the container cannot be cleared because the array element "1" still points to the array itself. Because there is no other symbol pointing to it, the user cannot clear this structure, and the result will cause memory leakage. Fortunately, php will clear the data structure at the end of the request, but it will consume a lot of memory before php purge. This often happens if you want to implement an analysis algorithm or do something like a child element pointing to its parent element. Of course, the same situation also occurs on the object, which is more likely to happen because the object is always implicitly referenced.

If the above situation occurs only once or twice, but if there are thousands or even hundreds of thousands of memory leaks, this is obviously a big problem. In a script that runs for a long time, such as a daemon that basically does not end a request or a large suite in a unit test, when you perform a unit test on the template component of the eZ component library, the latter (a large suite in the unit test) will encounter problems. it will consume 2 GB of memory, but the general test server does not have such a large memory space.

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.