Generally, php scripts do not need to consider Memory leakage and garbage collection, because the script will be executed and exited quickly. However, when the execution time is long and the processing data volume is large, the php script occupies too much memory after a period of time, and then reports an error (PHPFatalerror: Allowedmemorysizeof134217728bytesexhausted)
Generally, php scripts do not need to consider Memory leakage and garbage collection, because the script will be executed and exited quickly. However, when the execution time is long and the processing data volume is large, the php script occupies too much memory after running for a period of time, and an error is reported (PHP Fatal error: Allowed memory size of 134217728 bytes exhausted) return
Generally, php scripts do not need to consider Memory leakage and garbage collection, because the script will be executed and exited quickly. However, when the execution time is long and the processing data volume is large, the php script occupies too much memory after running for a period of time, and an error is reported (PHP Fatal error: Allowed memory size of 134217728 bytes exhausted) quit. In general, when the processing of each page ends, the new simple_html_dom object should be destroyed, but in fact it does not. It is obvious that memory leakage has occurred.
Garbage collection mechanism of PHP
The garbage collection mechanism used before php 5.3 is a simple "reference count", that is, each memory object is allocated with a counter. When the memory object is referenced by a variable, the counter is + 1; when the variable reference is removed, counter-1; when counter = 0, indicates that the memory object is not used, the memory object is destroyed, and garbage collection is completed.
There is a problem with "reference count", that is, when two or more objects reference each other to form a ring, the counter of the memory object will not be reduced to 0; at this time, this group of memory objects is useless, but cannot be recycled, resulting in Memory leakage.
Php5.3 started with a new garbage collection mechanism. Based on reference counting, it implemented a complex algorithm to detect the existence of reference rings in memory objects to avoid Memory leakage.
Check for Memory leakage
Check whether the released memory is not released. You can call the memory_get_usage function to check the memory usage. The memory usage data returned by the memory_get_usage function is said to be not very accurate. You can use the xdebug extension of php to obtain more accurate and informative memory usage.
class A{ private $b; function __construct(){ $this->b = new B($this); } function __destruct(){ //echo "A destruct\n"; }}class B{ private $a; function __construct($a){ $this->a = $a; } function __destruct(){ //echo "B descturct\n"; }}for($i=0;;$i++){ $a = new A(); if($i00 == 0){ echo memory_get_usage()."\n"; }}
The preceding example creates a ring reference. Every time you create instance A of object a, a creates instance B of object B and allows B to reference. In this way, each A object is always referenced by a B, and each B object is referenced by an object A at the same time, so the reference ring is generated.
When executing this code in the php5.2 environment, we will find that the memory usage increases monotonically, and there is no "A/B desctruct" information output after the Destructor A and B are executed; until the memory is exhausted, the output is "PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 40 bytes )". If you run this code in the php5.3 environment, you will find that the memory usage jumps up and down, but it never exceeds the limit. The program will also output A large number of "A/B desctruct", which indicates that the Destructor has been called.
The solution is also very simple, that is, when the simple_html_dom object is used up, it actively calls its clear function, clears its member variable nodes, the ring is broken, and the memory leakage will not happen.
Others
1. Garbage Collection Time
In PHP, if the reference count is 0, the memory is immediately released. That is to say, there is no variable referenced in the loop, and the memory is immediately released out of the scope of the variable. The ring reference detection is triggered when certain conditions are met. Therefore, in the above example, we can see that the memory usage fluctuates greatly. You can also use the gc_collect_cycles function to actively perform ring reference detection.
2. & Symbol impact
Explicitly referencing a variable increases the reference count of the memory:
$ A = "something ";
$ B = & $;
At this time, unset ($ a), but there is still a reference of $ B pointing to the memory area, the memory will not be released.
3. Impact of unset Functions
Unset only disconnects a variable from A memory area, and calculates the reference count of the memory area-1. In the preceding example, inside the loop body, $ a = new (); unset ($ a); does not reduce the reference count of $ a to zero;
4. Effect of = null operation
$ A = null: directly empty the data structure pointed to by $ a and return the reference count to 0.
5. Impact of script execution completion
After the script is executed, all memory used in the script will be released, regardless of whether there is a reference ring.
Original: http://abcd9.com /? Posting = 210
Original article address: PHP Memory leakage and garbage collection (simple_html_dom), thanks to the original author for sharing.