Home  >  Article  >  Backend Development  >  Understand the principles of PHP garbage collection in ten minutes

Understand the principles of PHP garbage collection in ten minutes

王林
王林Original
2019-09-04 09:52:484336browse

Understand the principles of PHP garbage collection in ten minutes

php garbage collection mechanism is a familiar but not very familiar content for PHPer. So how does PHP recycle unnecessary memory?

Memory storage structure of php variables:

First of all, you need to understand the basic knowledge to facilitate the understanding of the principles of garbage collection. Everyone knows that php is written in C, so the internal storage structure of php variables will also be related to the C language, that is, the structure of zval:

struct _zval_struct {
    union {
        long lval;
        double dval;
        struct {
            char *val;
            int len;
        } str;
        HashTable *ht;
        zend_object_value obj;
    } value;                    //变量value值
    zend_uint refcount__gc;   //引用计数内存中使用次数,为0删除该变量
    zend_uchar type;           //变量类型
    zend_uchar is_ref__gc;    //区分是否是引用变量
};

It can be seen from the content of the above structure that each php Variables will be composed of four parts: variable type, value value, reference count number and whether it is a reference variable

Note: The above zval structure is the structure after php5.3 version. Before php5.3, no new ones were introduced. The garbage collection mechanism is GC, so the name is not _gc; and after the PHP7 version, the zval structure was rewritten due to performance issues, so it will not be described here.

Principle of reference counting:

After understanding the internal storage structure of PHP variables, we will learn about the principles related to PHP variable assignment and the early garbage collection mechanism

Variable container

Non-array and object variables

Every time a constant is assigned to a variable, a variable container will be generated.

Example:

$a = '许铮的技术成长之路';
xdebug_debug_zval('a')

Result:

a: (refcount=1, is_ref=0)='许铮的技术成长之路'

array and object variables

will produce element numbers Variable container of number 1

Example:

$b = [
'name' => '许铮的技术成长之路',
'number' => 3
];
xdebug_debug_zval('b')

Result:

b: (refcount=1, is_ref=0)=array ('name' => (refcount=1, is_ref=0)='许铮的技术成长之路', 
'number' => (refcount=1, is_ref=0)=3)

Assignment principle (Copy-on-write technology)

After understanding the constant assignment, let’s think about the assignment between variables from the perspective of memory

Example:

$a = [
'name' => '许铮的技术成长之路',
'number' => 3
]; //创建一个变量容器,变量a指向给变量容器,a的ref_count为1
$b = $a; //变量b也指向变量a指向的变量容器,a和b的ref_count为2
xdebug_debug_zval('a', 'b');
$b['name'] = '许铮的技术成长之路1';//变量b的其中一个元素发生改变,此时会复制出一个新的变量容器,
变量b重新指向新的变量容器,a和b的ref_count变成1
xdebug_debug_zval('a', 'b');

Result:

a: (refcount=2, is_ref=0)=array ('name' => (refcount=1, is_ref=0)='许铮的技术成长之路', 'number' => (refcount=1, is_ref=0)=3)
b: (refcount=2, is_ref=0)=array ('name' => (refcount=1, is_ref=0)='许铮的技术成长之路', 'number' => (refcount=1, is_ref=0)=3)
a: (refcount=1, is_ref=0)=array ('name' => (refcount=1, is_ref=0)='许铮的技术成长之路', 'number' => (refcount=1, is_ref=0)=3)
b: (refcount=1, is_ref=0)=array ('name' => (refcount=1, is_ref=0)='许铮的技术成长之路1', 'number' => (refcount=1, is_ref=0)=3)

So, when When variable a is assigned to variable b, a new variable container is not immediately generated, but variable b is pointed to the variable container pointed by variable a, that is, the memory is "shared"; and when one element of variable b changes, Only then will the variable container copy actually occur. This is Copy on writeTechnology

The reference count is cleared to 0

When the ref_count of the variable container When the count is cleared to 0, it means that the variable container will be destroyed and memory recycling will be realized. This is also the garbage collection mechanism before php5.3 version

Example:

$a = "许铮的技术成长之路";
$b = $a;
xdebug_debug_zval('a');
unset($b);
xdebug_debug_zval('a');

Result:

a: (refcount=2, is_ref=0)='许铮的技术成长之路'
a: (refcount=1, is_ref=0)='许铮的技术成长之路'

Memory leak problem caused by circular reference:

But there is a loophole in the garbage collection mechanism before php5.3, that is, when the array Or the child element inside the object refers to its parent element, and if its parent element is deleted at this time, this variable container will not be deleted because its child elements are still pointing to the variable container, but since there is no The symbol pointing to the variable container cannot be cleared, so a memory leak will occur until the execution of the script ends.

Example:

$a = array( 'one' );
$a[] = &$a;
xdebug_debug_zval( 'a' );

Since this example does not output well, use Graphical representation, as shown in the figure:

Understand the principles of PHP garbage collection in ten minutes

Example:

unset($a);
xdebug_debug_zval('a');

As shown in the figure:

Understand the principles of PHP garbage collection in ten minutes

New garbage collection mechanism:

The root buffer mechanism was introduced after version 5.3 of php. That is, when php is started, the root buffer with the specified number of zvals is set by default (the default is 10000). When php finds that there is a circular reference zval, it will be put into the root buffer. When the root buffer reaches the specified number in the configuration file (the default is 10000), garbage collection will be performed to solve the memory leak problem caused by circular references

Criteria for confirming it is garbage:

1. If the reference count is reduced to zero, the variable container will be cleared (free) and is not garbage
2. If a After the reference count of zval is reduced and is still greater than 0, it will enter the garbage cycle. Secondly, during a garbage cycle, find out which parts are garbage by checking whether the reference count is reduced by 1 and checking which variable containers have zero references.

Summary:

Garbage collection mechanism:
1. Based on PHP’s reference counting mechanism (only this mechanism was available before PHP5.3)
2 , and use the root buffer mechanism at the same time. When PHP finds that there is a zval with a circular reference, it will put it into the root buffer. When the root buffer reaches the specified number in the configuration file, garbage collection will be performed. Solve the memory leak problem caused by circular references (php5.3 began to introduce this mechanism)

For more related questions, please visit the PHP Chinese website:php video tutorial

The above is the detailed content of Understand the principles of PHP garbage collection in ten minutes. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn