1. Reference Counting basic knowledge
Each PHP variable exists in a variable container called "Zval". A Zval variable container that includes two bytes of extra information in addition to the type and value of the variable. The first is "Is_ref", which is a bool value that identifies whether the variable belongs to a reference set (reference set). With this byte, the PHP engine can distinguish between ordinary variables and reference variables, and because PHP allows users to use custom references by using &, the Zval variable container also has an internal reference counting mechanism to optimize memory usage. The second extra byte is "RefCount", which represents the number of variables (also called symbol symbols) that point to the Zval variable container. All symbols exist in a table of symbols, where each symbol has scope (scope), and those main scripts (such as those that are requested by the browser) and each function or method also have scopes.
When a variable is assigned a constant value, a Zval variable container is generated, as in the following example:
<?php
$a = "wusuopubupt";
Xdebug_debug_zval (' a ');
$b = $a;
Xdebug_debug_zval (' a ');
Xdebug_debug_zval (' B ');
unset ($a);
Xdebug_debug_zval (' a ');
Xdebug_debug_zval (' B ');
Output:
A:
(Refcount=1, is_ref=0), String ' Wusuopubupt ' (length=11)
A:
(refcount=2, is_ref=0), String ' Wusuopubupt ' (length=11)
B:
(refcount=2, is_ref=0), String ' Wusuopubupt ' (length=11)
B:
(refcount=1 , is_ref=0), String ' Wusuopubupt ' (length=11)
As you can see, when variable A is just initialized, refcount=1, variable A is generated in the current scope. and a variable container of type string and value new string is generated. In the additional two bytes of information, "Is_ref" is set to FALSE by default because there are no custom reference builds. "RefCount" is set to 1 because there is only one variable a using this variable container. Note that when the value of "RefCount" is 1 o'clock, the value of "Is_ref" is always false.
Before unset ($a) is invoked, the RefCount (reference count) of A,b is 2, because there are 2 variables (a,b) that use this variable container.
After calling unset ($a), refcount (a) = 0, at which point the memory occupied by a is free, refcount (b) = 1, because there is only one variable b using this variable container
2. Garbage collection mechanism
2.1 First, we have to establish some basic rules, if a reference count increases, it will continue to be used, of course, no longer in the garbage. If the reference count is reduced to zero, the containing variable container is cleared (free). That is, the garbage cycle is generated only when the reference count is reduced to a value other than 0 (garbage cycle). Second, in a garbage cycle, find out which part is garbage by checking whether the reference count is minus 1 and checking which variable containers have a reference number of zero.
2.2PHP, the reference count RefCount to 0, the memory is released immediately. In other words, there is no ring-referenced variable, leaving the scope of the variable, and the memory is immediately released. Circular reference detection is triggered under certain conditions, so in the above example, you will see that the memory used has a large fluctuation. You can also use the Gc_collect_cycles function to actively perform ring reference detection.