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 are 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 ()NoRelease the memory of the parent object referenced in the sub-object (even if the parent object is garbage collected ).
Are you confused? Let's take a look at the following code:
<?php
class 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()) . "/n";
}
?>
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
33,551,976
33,552,336
33,552,696
PHP Fatal error: Allowed memory size of 33554432 bytes exhausted
(tried to allocate 16 bytes) in memleak.php on line 17
This 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:
<?php
class 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()) . "/n";
}
?>
Pay attention to the newly addedFoo ::__ 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 .) IndeedExist(An email), and received the attention of PHP kernel developers. The problem is whether the patch is not available in php5.3.Too many support.I think a good compromise is to call the _ destruct () method in the object in the unset () function;