The last time we talked about refcount and is_ref, we will talk about memory leakage.
$a = array(1, 2, &$a);unset($a);
In the old PHP version, memory leakage occurs. The analysis is as follows:
Run the first line to know the zval refcount = 2 and is_ref = 1 pointed to by $ A and $ A [2 ].
Then execute the second row. $ A will be deleted from the symbol table and directed to the zval refcount --. In this case, refcount = 1 because refcount! = 0, so zval will not be treated as garbage collection, but at this time we lose the entry of $ A [2] pointing to this zval, so this zval becomes a piece of memory garbage
The same principle can occur in internal class references, for example
$a = new Man();$a->self = &$a;unset($a);
So how can we solve this problem? The new GC mechanism uses an algorithm to solve this problem.
PHP has a root buffer used to store zval node information. When the root buffer is full or the GC function is manually called, the GC algorithm starts.
For an array or zval of the class type, when the garbage collection mechanism is enabled, the algorithm will traverse the zval of elements/members in the zval array/class and reduce refcount by 1. If the refcount of the zval is reduced to 0 after the traversal is complete, this zval is a memory spam and will be destroyed. See the following example.
$a = array(1, 2, &$a, &$a);unset($a);
It is easy to know the zval pointed to by $ A. Assume that refcount of z1 is 3, and is_ref is 1.
When unset ($ A) is executed, $ A has been deleted from the symbol table, and we also lose the entry to access Z1. At this time, Z1 refcount = 2, is_ref = 1
When GC is started, the zval refcount of the array element of the Z1 will be traversed minus 1 and traversed to a [2], Z1 refcount --, A [3] Z1 refcount --, at this time Z1 refcount = 0, you can mark Z1 as memory garbage, and the algorithm will recycle it
To sum up, it can be expressed as follows: if an array type zval is used to traverse its element zval, The refcount of the zval will be traversed at the same time. If the last refcount = 0 zval, it is garbage and needs to be recycled.