It can be seen that the array uses 1 more zval storage than the array length. Objects are similar. The storage representation of the array is given below
$a = array( 'one' );
$a[] =& $a;
xdebug_debug_zval( 'a' );
?>
Running results:
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 container of a and 1 are the same. As follows:
This forms a circular reference.
In PHP 5.2 and earlier versions, there is no dedicated garbage collector GC (Garbage Collection). When the engine determines whether a variable space can be released, it relies on the value of the refcount of the variable's zval. If refcount If it is 0, then the variable space can be released, otherwise it will not be released. This is a very simple GC implementation.
Now unset ($a), then the refcount of the array is reduced by 1 and becomes 1. Now there is no variable pointing to this zval, and the counter of this zval is 1 and will not be recycled.
Although there is no longer any symbol in a scope pointing to this structure (that is, the variable container), since the array element "1" still points to the array itself, this container cannot be cleared. Since there is no other symbol pointing to it, the user has no way to clear the structure, resulting in a memory leak. Fortunately, PHP will clear this data structure at the end of the request, but before PHP clears it, it will consume a lot of space in memory. This happens a lot if you're implementing a parsing algorithm, or doing other things like having a child element point to its parent. Of course, the same situation can happen with objects, in fact it is more likely to happen with objects, because objects are always implicitly referenced.
It’s okay if the above situation occurs only once or twice, but if memory leaks occur thousands or even hundreds of thousands of times, this is obviously a big problem. Problems can arise when running long-running scripts, such as daemons that rarely end when requesting them, and memory space will continue to be consumed, leading to out-of-memory crashes.
In PHP5.3, a special algorithm (more complex) is used. , to deal with the problem of memory leaks caused by circular references.
When a zval may be garbage, the collection algorithm will put the zval into a memory buffer. When the buffer reaches the maximum critical value (the maximum value can be set), the recycling algorithm will cycle through all zvals in the buffer to determine whether they are garbage and perform release processing. Or we use gc_collect_cycles in the script to force the garbage in the buffer to be recycled.
In the GC of php5.3, the garbage is explained as follows:
1: If the refcount of a zval increases, then this zval is still in use, it is definitely not garbage and will not enter the buffer
2: If the refcount of a zval is reduced to 0, then the zval will be released immediately. It is not a garbage object to be processed by the GC and will not enter the buffer.
3: If the refcount of a zval is greater than 0 after being reduced, then the zval cannot be released, and the zval may become garbage and be put into the buffer. The GC in PHP5.3 targets this kind of zval processing.
Turning on/off the garbage collection mechanism can be achieved by modifying the PHP configuration, or it can be turned on and off in the program using gc_enable() and gc_disable().
After turning on the garbage collection mechanism, a large amount of memory space can be saved in case of memory leaks. However, since the garbage collection algorithm takes time to run, turning on the garbage collection algorithm will increase the execution time of the script.
The following is a script given 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 = $a;
if ( $i % 500 === 0 )
{
echo sprintf( '%8d: ', $i ), memory_get_usage() - $baseMemory, "n";
}
}
?>
For this script, its memory usage in php5.2 and 5.3 is given, as shown below:
For the following script
class Foo
{
public $var = '3.1415962654';
}
for ( $i = 0; $i <= 1000000; $i++ )
{
$a = new Foo;
$a->self = $a;
}
echo memory_get_peak_usage(), "n";
?>
When the garbage collection mechanism is turned on, the script execution time increases by 7% compared to when it is not turned on
Usually, the garbage collection mechanism in PHP only increases the time consumption when the recycling algorithm is actually running. But in normal (smaller) scripts there should be no performance impact at all.
http://www.bkjia.com/PHPjc/938943.htmlwww.bkjia.comtruehttp: //www.bkjia.com/PHPjc/938943.htmlTechArticleDetailed explanation of PHP’s garbage collection mechanism. Recently, I wrote a script using php to simulate the implementation of a daemon process, so I need In-depth understanding of the garbage collection mechanism in PHP. This article refers to...
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