Explanation of PHP garbage collection mechanism _ PHP Tutorial

Source: Internet
Author: User
The garbage collection mechanism of PHP is described in detail. The garbage collection mechanism of PHP is explained in detail recently because a script is written in php to simulate a daemon process, it is necessary to have a deep understanding of the garbage collection mechanism in php. This article describes the garbage collection mechanism of PHP.
Recently, a script has been written in php to simulate a daemon process. Therefore, you need to have a thorough understanding of the garbage collection mechanism in php. This document references the PHP Manual.

Before understanding the garbage collection mechanism (GC) of PHP, let's take a 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, apart from storing the type and value of the variable, there are also the is_ref field and refcount field.

Is_ref: a bool value used to identify whether a variable belongs to a reference set. What do you mean? you can think like this: whether the variable has more than one alias.

Refcount: counter, indicating the number of variables pointing to the zval variable container.

There is a default relationship between the two: when the refcount value is 1, the is_ref value is false. Because refcount is 1, this variable cannot have multiple aliases, so there is no reference.

After the xdebug extension is installed, you can use xdebug_debug_zval to print the zval container details.

Note that when a variable = is assigned to another variable, it does not immediately allocate memory space for the new variable, but adds 1 to refcount in the original variable zval. The memory space is allocated for the new variable only when the original variable or change occurs, and the refcount of the original variable is reduced by 1. Of course, if you unset the original variable, the new variable directly uses the zval of the original variable instead of reallocation.

& When a value is referenced, the is_ref of the original variable is changed to 1, and refcount is added to 1. if a variable & value is assigned, the variable = previously assigned will allocate space.

$ A = 1;

Xdebug_debug_zval ('A ');

Echo PHP_EOL;

$ B = $;

Xdebug_debug_zval ('A ');

Echo PHP_EOL;

$ C = & $;

Xdebug_debug_zval ('A ');

Echo PHP_EOL;

Xdebug_debug_zval ('B ');

Echo PHP_EOL;

?>

The running result is 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 mentioned above stores the scalar. how is the composite array stored?

$ A = array ('meaning' => 'life', 'number' => 42 );

Xdebug_debug_zval ('A ');

Echo PHP_EOL;

Class Test {

Public $ a = 1;

Public $ B = 2;

Function handle (){

Echo 'hehes ';

}

}

$ Test = new Test ();

Xdebug_debug_zval ('test ');

?>

The running result is as follows:

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

Array

'Meaning' => (refcount = 1, is_ref = 0 ),

String

'Life' (length = 4)

'Number' => (refcount = 1, is_ref = 0 ),

Int

42

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

Object (Test) [1]

Public 'a' => (refcount = 2, is_ref = 0 ),

Int

1

Public 'B' => (refcount = 2, is_ref = 0 ),

Int

2

It can be seen that the array uses one zval storage longer than the array length. The object is similar. The storage image representation of the array is given below

We can see that the array is allocated with three zval containers: a meaning number

Now let's take a look at how the so-called ring reference is generated.

$ A = array ('one ');

$ A [] = & $;

Xdebug_debug_zval ('A ');

?>

Running result:

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

Array

0 => (refcount = 1, is_ref = 0 ),

String

'One' (length = 3)

1 => (refcount = 2, is_ref = 1), & array

The zval containers of a and 1 are the same. As follows:

In this way, a ring reference is formed.

In PHP 5.2 and earlier versions, there is no dedicated Garbage collector GC (Garbage Collection ), the engine determines whether a variable space can be released based on the zval refcount value of the variable. if the refcount is 0, the variable space can be released; otherwise, the variable space will not be released, this is a very simple GC implementation.

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

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. If a script that runs for a long time, such as a daemon process that basically does not end a request, it will cause problems and the memory space will be continuously consumed, resulting in insufficient memory and crash.

PHP5.3 uses specialized algorithms (more complex )., To handle the memory leakage caused by ring references.

When a zval may be spam, the recycle algorithm will put this zval into a memory buffer. When the buffer reaches the maximum critical value (the maximum value can be set), the recycle algorithm cyclically traverses the zval in all the buffers to determine whether it is spam and release it. Or we can use gc_collect_cycles in the script to forcibly recycle the garbage in the buffer zone.

In the GC of php5.3, the spam is described as follows:

1: If the refcount of a zval is increased, zval is still in use and will not enter the buffer zone.

2: If the refcount of a zval is reduced to 0, zval will be released immediately. it does not belong to the garbage object to be processed by the GC and will not enter the buffer zone.

3: If the refcount of a zval is reduced and greater than 0, the zval cannot be released. this zval may become a garbage and be placed in the buffer zone. GC in PHP5.3 is for processing this zval.

To enable or disable the garbage collection mechanism, you can modify the php configuration, or use gc_enable () and gc_disable () in the program to enable or disable the mechanism.

After the garbage collection mechanism is enabled, memory leakage can save a lot of memory space. However, because the garbage collection algorithm takes time to run, enabling the garbage collection algorithm will increase the script execution time.

The following is a script in the php Manual.

Class Foo

{

Public $ var = '3. 1415962654 ';

}

$ BaseMemory = memory_get_usage ();

For ($ I = 0; $ I <= 100000; $ I ++)

{

$ A = new Foo;

$ A-> self = $;

If ($ I % 500 = 0)

{

Echo sprintf ('% 8d:', $ I), memory_get_usage ()-$ baseMemory, "\ n ";

}

}

?>

  

This script shows the memory usage in php5.2 and 5.3, for example:

For the following script

Class Foo

{

Public $ var = '3. 1415962654 ';

}

For ($ I = 0; $ I <= 1000000; $ I ++)

{

$ A = new Foo;

$ A-> self = $;

}

Echo memory_get_peak_usage (), "\ n ";

?>

  

When the garbage collection mechanism is enabled, the script execution time is increased by 7% compared with when it is not enabled.

Generally, the garbage collection mechanism in PHP only increases the time consumption when the loop collection algorithm does run. However, in normal (smaller) scripts, there should be no performance impact at all.

Ghost recently used php to write a script to simulate a daemon process, so it is necessary to have a deep understanding of the garbage collection mechanism in php. This article references...

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.