A detailed explanation of the PHP garbage collection mechanism

Source: Internet
Author: User

The original: PHP garbage collection Mechanism detailed

Recently, because a script was written using PHP, the simulation implements a daemon, and therefore requires a deep understanding of the garbage collection mechanism in PHP. This article refers to the PHP manual.

Before understanding the PHP garbage collection mechanism (GC), let's look at the storage of variables.

The variables in PHP exist in a Zval variable container. The structure is as follows:

Type

Value

Is_ref

RefCount

In Zval, there are is_ref fields and RefCount fields in addition to the types and values of stored variables.

    • Is_ref: is a bool value that distinguishes whether a variable belongs to a reference collection. What do you mean, you can think of it this way: Indicates whether the variable has more than one alias.
    • RefCount: Counter that represents the number of variables that point to the Zval variable container.

There is a default relationship between the two: when the RefCount value is 1 o'clock, the value of Is_ref is false. Because RefCount is 1, this variable cannot have more than one alias, and there is no reference.

After installing Xdebug expansion, you can print out Zval container details using Xdebug_debug_zval.

One thing to note here is that assigning a variable = to another variable does not immediately allocate memory space for the new variable, but adds 1 to refcount in the zval of the original variable. Only when the original variable or changes, the new variable is allocated memory space, while the original variable refcount minus 1. Of course, if unset the original variable, the new variable directly uses the Zval of the original variable instead of reassigning it.

& When a reference is assigned, the is_ref of the original variable becomes 1,refcount plus 1. If a variable & assignment is given, the previously = assigned variable allocates space.

<?php $a = 1;xdebug_debug_zval (' a '); echo php_eol; $b = $a; Xdebug_debug_zval (' a '); echo php_eol; $c = & $a; xdebug_ Debug_zval (' a '); Echo php_eol;xdebug_debug_zval (' B '); Echo php_eol; >

The results of the operation are as follows:

A:(refcount=1, is_ref=0),int 1

A:(refcount=2, is_ref=0),int 1

A:(refcount=2, is_ref=1),int 1

B:(Refcount=1, is_ref=0),int 1

The zval described above stores a scalar, how does an array of compound types be stored?

<?php $a = array (' meaning ' = ' life ', ' number ' = '); Xdebug_debug_zval (' a '); Echo Php_eol;class Test{public $ A = 1;public $b = 2;function handle () {echo ' hehe ';}} $test = new test (); Xdebug_debug_zval (' Test ');? >

The results of the operation are as follows:

A:(refcount=1, is_ref=0),

Array  = (Refcount=1, is_ref=0),

String

' Life ' (length=4)
  = (Refcount=1, is_ref=0),

Int

42

Test:(refcount=1, is_ref=0),

Object (Test) [1]   Public = (refcount=2, is_ref=0),

Int

1
   Public = (refcount=2, is_ref=0),

Int

2

As you can see, the array is stored with one more zval than the array length. objects are similar. The storage image representation of the array is given below.

You can see that the array is assigned three zval containers: a meaning number

Now look at how the so-called circular reference is generated.

<?php$a = Array (' one '); $a [] =& $a; Xdebug_debug_zval (' a ');? >

Operation Result:

A:(refcount=2, is_ref=1),

Array  = (Refcount=1, is_ref=0),

String

' One ' (length=3)
  = (refcount=2, is_ref=1) & Array

The Zval container of a and 1 is the same. As follows:

This creates a circular reference.

In PHP 5.2 and earlier, there is no dedicated garbage collector GC (garbage Collection), the engine in determining whether a variable space can be released is based on the Zval refcount value of this variable, if RefCount is 0, Then the variable space can be freed, otherwise it is not released, this is a very simple GC implementation.

Now unset ($a), then the refcount of the array is reduced by 1 to 1. Now there is no variable pointing to this zval, and this zval counter is 1 and will not be recycled.

Although there is no longer any symbol in a scope pointing to the structure (that is, the variable container), the array element "1" still points to the array itself, so the container cannot be cleared. Because there is no additional symbol pointing to it, the user has no way to clear the structure, resulting in a memory leak. Fortunately, PHP will erase this data structure at the end of the request, but it will consume a lot of memory before PHP clears. This happens frequently if you want to implement an analytic algorithm, or if you want to do something like a child element that points to its parent element. Of course, the same is true for objects, which are actually more likely to occur because objects are always implicitly referenced.

If the situation above is nothing but one or two times, it is obviously a big problem if there are thousands of or even hundreds of thousands of memory leaks. A long-running script, such as a daemon that basically does not end, can cause problems, memory space is constantly consumed, and memory is not enough to crash.

In PHP5.3, a special algorithm is used (more complex). To handle the issue of memory leaks caused by ring references.

When a zval may be garbage, the recovery algorithm puts the zval into a memory buffer. When the buffer reaches the maximum critical value (the maximum value can be set), the recycle algorithm loops through all the buffers in the Zval, determines whether it is garbage, and releases the processing. Or we use gc_collect_cycles in our script to force garbage collection in the buffer.

In the GC of php5.3, the following instructions were made for the garbage:

1: If a zval refcount increases, then this zval is still in use, certainly not garbage, will not enter the buffer

2: If a zval refcount is reduced to 0, then Zval will be released immediately, not a garbage object that the GC will process, and will not enter the buffer.

3: If a zval refcount is reduced by more than 0, then this zval cannot be released, and the Zval may become a garbage and put it into a buffer. The GC in PHP5.3 is for this kind of zval processing.

The On/off garbage collection mechanism can be implemented by modifying the PHP configuration or by using gc_enable () and gc_disable () to turn on and off in the program.

When the garbage collection mechanism is turned on, the memory leaks can save a lot of memory space, but because the garbage collection algorithm runs time-consuming, turning on the garbage collection algorithm increases the execution time of the script.

Here is a script given in the PHP manual

<?phpclass foo{public    $var = ' 3.1415962654 ';} $baseMemory = Memory_get_usage (); for ($i = 0; $i <= 100000; $i + +) {    $a = new Foo;    $a->self = $a;    if ($i% = = 0)    {        echo sprintf ('%8d: ', $i), Memory_get_usage ()-$baseMemory, "\ n";    }}? >

  

For this script, the memory usage in php5.2 and 5.3 is given, such as:

For the following script

<?phpclass foo{public    $var = ' 3.1415962654 ';} for ($i = 0; $i <= 1000000; $i + +) {    $a = new Foo;    $a->self = $a;} Echo memory_get_peak_usage (), "\ n";? >

  

The garbage collection mechanism is turned on, and the script execution time is increased by 7% relative to non-open.

In general, the garbage collection mechanism in PHP has a time-consuming increase only when the recycle algorithm is actually running. However, there should be no performance impact at all in the usual (smaller) script.


A detailed explanation of the PHP garbage collection mechanism

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.