Mutual reference of PHP Objects memory overflow _ PHP Tutorial

Source: Internet
Author: User
Memory overflow of mutual reference of PHP Objects. One of the biggest advantages of using a scripting language is that it can use its automatic garbage collection mechanism (releasing memory ). You do not need to release the memory after using the variable. PHP will

One of the biggest advantages of using a scripting language is that it can use its automatic garbage collection mechanism (releasing memory ). You do not need to release the memory after using the variable. PHP will help you.
Of course, we can call the unset () function as needed to release the memory, but this is usually not required.
However, in PHP, memory is not automatically released in at least one case, even when unset () is called manually (). Details available: http://bugs.php.net/bug.php? Id = 33595.

Symptom
If there is a mutual reference relationship between the two objects, such as "parent object-sub-object", call unset () for the parent object () the memory of the parent object referenced in the sub-object is not released (even if the parent object is reclaimed by garbage collection ).
Are you confused? Let's take a look at the following code:

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 will see that the memory usage is getting higher and higher until the light is used up.

... 33,551,616 97633,552,336, 33554432, 696PHP Fatal error: Allowed memory size of bytes exhausted (tried to allocate 16 bytes) in memleak. php on line 17 is not a problem for most PHP programmers.
However, if you use a lot of referenced objects in a long-running code, especially when the object is relatively large, the memory will be quickly exhausted.

Userland solution
Although tedious and not elegant, a solution is provided in the previously mentioned bugs.php.net link.
This solution uses a destructor method before releasing an object to achieve the goal. The Destructor method can clear all internal parent object references, that is, it can release the memory that would have been overflows.
The following is the "fixed" code:

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 newly added Foo ::__ destruct () method and call $ foo->__ destruct () before releasing the object. Now this code solves the problem of increasing memory usage, so that the code can work well.

PHP kernel solution?
Why is memory overflow? I am not proficient in PHP kernel research, but it is certain that this problem is related to reference count.
The reference count for referencing $ foo in $ bar will not decrease because the parent object $ foo is released. in this case, PHP considers that you still need the $ foo object and will not release this part of memory ...... This is probably the case.
It can be seen that I am ignorant, but it generally means that the reference count is not decreasing, so some memory will never be released.
In the above-mentioned bugs.php.net link, I can see that the process of modifying garbage collection will sacrifice a lot of performance, because I do not know much about the reference count, so I think this is true.
Instead of changing the garbage collection process, why don't unset () be used to release internal objects? (Or call _ destruct () when releasing an object ()?)
Maybe PHP kernel developers can modify this garbage collection mechanism here or elsewhere.
Update: Martin Fjordvald mentioned a patch written by David Wang for garbage collection (in fact, it looks more like a whole piece of cloth-very huge. For details, see the CVS export information at the end of this email .) It does exist (an email) and has been noticed by PHP kernel developers. The problem is that this patch does not get much support in PHP5.3. I think a good compromise is to call the _ destruct () method in the object in the unset () function;

Memory ). You do not need to release the memory after using the variable. PHP will...

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.