PHP对象相互引用的内存溢出实例分析
《PHP对象相互引用的内存溢出实例分析》要点: PHP实例通常来说使用脚本语言最大的好处之一就是可利用其拥有的自动垃圾回收机制来释放内存.你不需要在使用完变量后做任何释放内存的处理,因为这些PHP会帮你完成. PHP实例问题症状如下: PHP实例如果两个对象之间存在着相互引用的关系,如“父对象-子对象”,对父对象调用 unset()不会释放在子对象中引用父对象的内存(即便父对象被垃圾回收,也不行). PHP实例是不是有些糊涂了?我们来看下面的这段代码: PHP实例
<?
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()) . " ";
}
?>
PHP实例运行这段代码,你会看到内存使用率越来越高越来越高,直到用光光. PHP实例
...33,551,61633,97633,552,33633,696PHP Fatal error: Allowed memory size of 33554432 bytes exhausted(tried to allocate 16 bytes) in memleak.php on line 17
PHP实例对大部分PHP程序员来讲这种情况不算是什么问题.可如果你在一个长期运行的代码中使用到了一大堆相互引用的对象,尤其是在对象相对较大的情况下,内存会迅速地消耗殆尽. PHP实例Userland办理方案 PHP实例虽然有些乏味、不优雅,但之前提到的 bugs.php.net 链接中提供了一个解决方案. PHP实例以下是“修复后”的代码: PHP实例
<?
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()) . " ";
}
?>
PHP实例注意那个新增的Foo::__destruct()办法,以及在释放对象前对 $foo->__destruct() 的调用.现在这段代码解决了内存使用率一直增加的问题,这么一来,代码就可以很好的工作了. PHP实例PHP内核办理方案 PHP实例为什么会有内存溢出的发生?我对PHP内核方面的研究并不精通,但可以确定的是此问题与引用计数有关系. PHP实例通俗的来说,大体意思是:一个引用计数没有递减,所以一些内存永远得不到释放. PHP实例与其改变垃圾回收的过程,为什么不用 unset() 对内部对象做释放的工作呢?(或者在释放对象的时候调用 __destruct()?) PHP实例相信本文所述对大家深入理解PHP运行原理有所赞助. 编程之家培训学院每天发布《PHP对象相互引用的内存溢出实例分析》等实战技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培养人才。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |