PHP's memory leak problem and garbage collection

Source: Internet
Author: User

You write a PHP script, generally do not consider memory leaks and garbage collection problems, because in general, your script will be executed soon after the exit.

But in some long run time, the data volume is large, the program runs for a period of time, the PHP script takes up too much memory, and then the error (PHP Fatal error:allowed memory size of 134217728 bytes exhausted) exited. In general, when each page is processed, the new Simple_html_dom object should be destroyed-but not really, obviously, a memory leak has occurred.

The garbage collection mechanism of PHP

The garbage collection mechanism used before PHP5.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 loop, the memory object's counter is not reduced to 0, and this set of memory objects is useless, but cannot be reclaimed, causing a memory leak.

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.

See if memory leaks

See if the freed memory is not released, you can simply call the Memory_get_usage function to see the memory usage to judge; The memory usage data returned by the Memory_get_usage function is said to be inaccurate, and you can use PHP's xdebug extension to get more Accurate and informative memory usage.

classa{Private $b; function__construct () {$this->b =NewB$this); }    function__destruct () {//echo "A destruct\n";    }}classb{Private $a; function__construct ($a){        $this->a =$a; }    function__destruct () {//echo "B descturct\n";    }} for($i= 0;;$i++){    $a=NewA (); if($i xx= = 0){        EchoMemory_get_usage (). " \ n "; }}

The above constructs an example of a ring-like reference. Each time you create an instance of a A,a object, you create an instance B of the B object and let B refer to a. Thus, each a object is always referenced by a B, and each B object is referenced by an object A at the same time, and the reference ring is created.

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 is jumping up and down, but never exceeding a limit. The program also 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.

Other

1. Timing of garbage collection

In PHP, the reference count is 0, and the memory is released immediately. That is, there is no ring-referenced variable, and the memory is released immediately, leaving the scope of the variable. Ring-reference detection is triggered under certain conditions, so in the example above, you will see that the memory used has a large fluctuation. You can also use the Gc_collect_cycles function to actively perform circular reference detection.

2. Impact 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. Effects of the 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. = Effect of NULL operation

$a = NULL is NULL to direct the data structure pointed to by $ A and its reference count to 0.

5. Impact 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.

Original address: http://blog.snsgou.com/post-181.html

PHP's memory leak problem and garbage collection

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.