The garbage collection mechanism of PHP features-the collection cycle is traditionally like the reference counting memory mechanism used by php in the past, which cannot handle cyclic reference memory leakage. However, 5.3.0 PHP uses the article» Reference the synchronization algorithm in the count system (Concurrent Cycle Collection in Reference Counted Systems) to handle this memory leakage problem.
The complete description of the algorithm is a bit out of the scope of this part. we will only introduce the basic part. First, we need to establish some basic rules. if a reference count increases, it will continue to be used, and of course it will not be in the garbage. If the reference count is reduced to zero, the variable container is cleared (free ). That is to say, garbage cycle is generated only when the reference count is reduced to a non-zero value ). Second, in a garbage cycle, check whether the reference count is reduced by 1, and check which variable containers reference zero times to find which part is garbage.
To avoid having to check all the garbage cycles that may reduce the reference count, this algorithm places all possible roots (possible roots are zval variable containers) in the root buffer) to ensure that each possible spam root (possible garbage root) appears only once in the buffer zone. Garbage collection is performed on all variable containers in the buffer zone only when the root buffer is full. See Step.
In Step B, the algorithm uses a deep-first search to find all possible roots, and then removes the reference count in each variable container by "1 ", to ensure that "1" is not subtracted twice for the same variable container, use the gray mark that "1" has been subtracted. In Step C, the algorithm uses deep-first search for each root node again to check the reference count of each variable container. If the reference count is 0, the variable container is marked in white (blue in the figure ). If the number of references is greater than 0, the operation that uses the deep preference search on this point and removes the reference count by "1" (that is, the reference count plus "1") is resumed "), then they are marked with black again. In step D, the algorithm traverses the root buffer to delete the variable container root (zval roots) from there, and checks whether there are variable containers marked White in the previous step. Each variable container marked with white is cleared.
Now you have a basic understanding of this algorithm. let's look back at how to integrate it with PHP. By default, PHP's garbage collection mechanism is enabled, and a php. ini setting allows you to modify it: zend. enable_gc.
When the garbage collection mechanism is enabled, the loop search algorithm described above is executed whenever the root cache is full. The root cache has a fixed size, which can store 10,000 possible roots. of course, you can modify this 10,000 value by modifying the constant GC_ROOT_BUFFER_MAX_ENTRIES in the PHP source file Zend/zend_gc.c, and then re-compiling PHP. When the garbage collection mechanism is disabled, the cyclic search algorithm never runs. However, the root may remain in the root buffer, regardless of whether the garbage collection mechanism is activated in the configuration.
When the garbage collection mechanism is disabled, if the root buffer is full, the root may not be recorded. The root of unrecorded records will not be analyzed and processed by this algorithm. If they are part of a cycle reference period, they will never be cleared, resulting in memory leakage.
Even if the garbage collection mechanism is unavailable, the root may be recorded because the record operation may be faster than checking whether the garbage collection mechanism is enabled after the root is found. However, the garbage collection and analysis mechanism takes a lot of time.
In addition to modifying the configuration zend. enable_gc, you can call the gc_enable () and gc_disable () functions to enable and disable the garbage collection mechanism. Calling these functions is the same as modifying configuration items to enable or disable the garbage collection mechanism. Even if the root buffer is not full, periodic recovery can be enforced. You can call the gc_collect_cycles () function to achieve this goal. This function returns the number of cycles collected using this algorithm.
The reason that the garbage collection mechanism is enabled and disabled and independent initialization is allowed is that some part of your application may be highly time-sensitive. In this case, you may not want to use the garbage collection mechanism. Of course, disabling the garbage collection mechanism for some part of your application is at risk of memory leakage, because some may not store in a limited root buffer. Therefore, it may be wise to call the gc_collect_cycles () function before you call the gc_disable () function to release the memory. This will clear all possible roots that have been stored in the root buffer, and then leave an empty buffer when the garbage collection mechanism is disabled to have more storage potential roots.