PHP can automate memory management to remove objects that are no longer needed. PHP uses the simple garbage collection (garbage collection) mechanism of the reference count (reference counting). Each object contains a reference counter, each reference connected to the object, and the counter is incremented by 1. When reference leaves the living space or is set to NULL, the counter is reduced by 1. When a reference counter of an object is zero, PHP knows that you will no longer need to use this object to free up its occupied memory space
The garbage collection mechanism used before PHP 5.3 is a simple "reference count", that is, each memory object is assigned a counter, when the memory object is referenced by a variable, counter +1; When the variable reference is removed, the counter-1; when the counter = 0 o'clock indicates that the memory object is not being used, the memory object is destroyed. Garbage collection is complete.
The problem with reference counting is that when two or more objects reference each other to form a ring, the counter of the memory object is not reduced to 0; At this time, this set of memory objects is useless, but cannot be recycled, resulting in memory leaks;
php5.3 started with a new garbage collection mechanism, based on reference counting, a complex algorithm was implemented to detect the existence of reference rings in memory objects to avoid memory leaks.
PHP variables exist in a variable container called "Zval", the "zval" variable container includes the type and value of the variable, and also includes an additional two bytes of information, respectively, "Is_ref" indicates whether the variable is a reference, "RefCount" points to the number of variables in this zval variable container.
If you install Xdebug, you can use Xdebug_debug_zval () to display the "Zval" message. As follows:
$str = "www.bKjia.c0m";
Xdebug_debug_zval (' str ');
Results:
Str:
(Refcount=1, is_ref=0),
String ' phpddt.com ' (length=10)
The variable container is destroyed only when "RefCount" becomes 0 o'clock. When you unset () a variable, the refcount in the desired "zval" will be reduced by 1, then the unset reference problem encountered in the previous days:
| The code is as follows |
Copy Code |
$a = "AAA"; $b = & $a; unset ($a); Echo $b; This will still output AAA, print with Xdebug_debug_zval and you'll know why. Xdebug_debug_zval ("B"); Results: B: (Refcount=1, is_ref=0), String ' aaa ' (length=3) |
Continue to refer to the counter problem, which is different for array and object conforming types:
| code as follows |
copy code |
| "!--? php $arr = Array (' A ' = ' aaa ', ' b ' = ' BBB '); Xdebug_debug_zval (' arr '); $arr [' aaa '] = $arr [' a ']; Xdebug_debug_zval (' arr '); ? Result: Arr: (refcount=1, is_ref=0), Array ' a ' + = (refcount=1, is_ref=0), String ' AAA ' (length=3) ' b ' = = (Refcount=1, is_ref=0), String ' BBB ' (length=3) Arr: (Refcount=1, is_ref=0), Array ' a ' = = (refcount=2, is_ref=0), String ' aaa ' (length=3) ' b ' = = (Refcount=1, is_ref=0), String ' BBB ' (length=3) ' aaa ' = (refcount=2, is_ref=0), String ' aaa ' (length=3) |
You can see that the original array element and the newly added array element are associated to the Zval variable container of the same "RefCount" 2. I'm just playing a role here.
We're simply using the unset,null,mysql_close,__destruct,xdebug_debug_zval and then looking down.
See if memory leaks
To see if any of the freed memory is not released, you can simply call the Memory_get_usage function to see memory usage to determine; the memory usage data returned by the Memory_get_usage function is said to be inaccurate and can be used in PHP xdebug To get more accurate and informative memory usage.
| |
copy code |
| class a{ private $b; Function __ Construct () { $this->b = new B ($this); } Function __destruct () { //echo "A destructn"; } } Class b{ private $a; function __construct ($a) { $this->a = $a; } Function __destruct () { //echo "B descturctn"; } } for ($i = 0;; $i + +) { $a = new A (); if ($i%1000 = = 0) { echo memory_get_usage (). " n "; } } } |
The above constructs an example of a circular reference, each time an instance of a a,a is created, an instance B of a B object is created, and B is referenced by A; so that each a object is always referenced by a B, and each B object is referenced by an object A at the same time; The reference ring is generated.
Executing this code in a php5.2 environment will find that the memory usage is increasing monotonically, and there is no "A/b desctruct" information output after the destructors of A and B. are executed, until the memory runs out, output "PHP Fatal error:allowed memory size of 134217728 bytes exhausted (tried to allocate-bytes) ".
Executing this code in a php5.3 environment, it is found that memory usage jumps up and down, but never exceeds a limit, and the program outputs a large number of "A/b desctruct", which means that the destructor is called.
In my colleague's program, there is this kind of reference loop, and his script is actually php5.2.3 under execution. Simple_html_dom tool, there are two classes, respectively, Simple_html_dom and Simple_html_dom_node, the former has an array member variable nodes, the array of each element is a simple_html_dom_ Node object, and each Simple_html_dom_node object has a member variable DOM, the value of which is the previous Simple_html_dom object-This creates a nice reference ring, which results in a memory leak. The solution is also very simple, that is, when the Simple_html_dom object is used, the active call its clear function, empty its member variable nodes, the ring is broken, the memory leak will not happen.
3. Other:
1) Timing of garbage collection
In PHP, the reference count is 0, then the memory is released immediately; that is, there is no ring-referenced variable, leaving the scope of the variable, and the memory is released immediately.
Ring-referenced detection is triggered under certain conditions, so in the above example, you will see a large amount of fluctuations in the memory used, or you can use the Gc_collect_cycles function to actively do ring-referenced detection.
2) Effects of & symbols
Explicitly referencing a variable increases the reference count for that memory:
$a = "something";
$b = & $a;
At this point unset ($a), but there is still a reference to the memory area $b, memory is not freed.
3) Effect of unset function
unset just disconnects a variable into a block of memory, and the reference count of that memory area is 1; In the above example, inside the loop body, $a =new a (); unset ($a); The reference count of $ A will not be reduced to zero;
4) = The effect of the null operation;
$a = NULL is NULL to direct the data structure pointed to by $ A and its reference count to 0.
5) Effect of end of script execution
At the end of the script execution, all memory used in the script is freed, regardless of the reference ring.
http://www.bkjia.com/PHPjc/628717.html www.bkjia.com true http://www.bkjia.com/PHPjc/628717.html techarticle PHP can automate memory management to remove objects that are no longer needed. PHP uses the simple garbage collection (garbage collection) mechanism of the reference count (reference counting). Each object is inside ...