A memory overflow instance with reference to PHP objects _php tips

Source: Internet
Author: User
Tags garbage collection memory usage php website

In general, one of the great benefits of using scripting languages is that you can use the automatic garbage collection mechanism that it has to free up memory. You don't have to do any free memory processing after using the variables, because these PHP will help you complete.
Of course, we can call the unset () function to free up memory as we wish, but this is not usually necessary.
In PHP, however, there is at least one situation where memory is not automatically released, even if it is manually invoked unset (). The details of the PHP website on the memory leak analysis: http://bugs.php.net/bug.php?id=33595.

Problem symptoms are as follows:

If two objects have a cross-reference relationship, such as "Parent object-child object", calling Unset () on the parent object does not release the memory that references the parent object in the child object (even if the parent object is garbage collected).

Are you a little confused? Let's look at the following code:

?
Phpclass Foo {
 function __construct () {
 $this->bar = new Bar ($this);
 }
}
Class Bar {
 function __construct ($foo = null) {
 $this->foo = $foo;
 }
}
while (true) {
 $foo = new Foo ();
 Unset ($foo);
 Echo Number_format (Memory_get_usage ()). " ";
}
? >

Run this code and you'll see that the memory usage is getting higher and higher until the light runs out.

... 33,551,61633,551,97633,552,33633,552,696php Fatal error:allowed Memory size of 33554432 bytes exhausted (tried to allocat e-bytes) in memleak.php on line 17

This is not a problem for most PHP programmers. But if you use a lot of references in a long-running code, especially if the object is relatively large, the memory will run out quickly.

Userland Solutions

Although somewhat tedious and not elegant, a solution is provided in the previously mentioned bugs.php.net link.
This scheme uses a destructor method to achieve the goal before releasing the object. The destructor method clears all internal parent object references, which means that the portion of memory that would otherwise overflow can be freed.

Here is the code after "fix":

?
Phpclass Foo {
 function __construct () {
 $this->bar = new Bar ($this);
 }
 function __destruct () {
 unset ($this->bar);
 }
Class Bar {
 function __construct ($foo = null) {
 $this->foo = $foo;
 }
}
while (true) {
 $foo = new Foo ();
 $foo->__destruct ();
 Unset ($foo);
 Echo Number_format (Memory_get_usage ()). " ";
}
? >

Note the new Foo::__destruct () method, and the call to $foo->__destruct () before the object is disposed. Now that the code solves the problem of increasing memory usage, the code can work well.

PHP Kernel Solution

Why is there a memory overflow happening? My research on the PHP kernel is not proficient, but it is certain that the problem is related to the reference count.
Reference counts that reference $foo in the $bar are not decremented because the parent object $foo released, and PHP thinks you still need $foo object and will not release that part of the memory. The principle is roughly the same.

Generally speaking, the general meaning is: a reference count does not decrease, so some memory will never be released.
In addition, it is pointed out in the bugs.php.net link mentioned earlier that the process of modifying garbage collection will sacrifice a great deal of performance, requiring readers to pay attention to this.

Rather than changing the process of garbage collection, why not unset () the task of releasing internal objects? (or call __destruct () when you release the object?) )
Perhaps the PHP kernel developer can make changes to this garbage collection mechanism here and elsewhere.

I believe this article will help you understand the principles of PHP operation.

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.