专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »PHP教程 » 内存溢出:PHP对象相互引用的内存溢出 »正文

内存溢出:PHP对象相互引用的内存溢出

来源: 发布时间:星期一, 2009年1月12日 浏览:61次 评论:0
  使用脚本语言最大好处的就是可利用其拥有自动垃圾回收机制(释放内存)你不需要在使用完变量后做任何释放内存处理PHP会帮你完成

  当然我们可以按自己意愿 un 来释放内存但通常不需要这么做

  不过在PHP里至少有种情况内存不会得到自动释放即便是手动 un详情可考:http://bugs.php.net/bug.php?id=33595

  问题症状

  如果两个对象的间存在着相互引用关系如“父对象-子对象”对父对象 un不会释放在子对象中引用父对象内存(即便父对象被垃圾回收也不行)

  有些糊涂了?我们来看下面这段代码:

  <?php Foo {function __construct{$this->bar = Bar($this);}} Bar {function __construct($foo = null){$this->foo = $foo;}}while (true) {$foo = Foo;un($foo);echo number_format(memory_get_usage) . "n";}?>运行这段代码你会看到内存使用率越来越高越来越高直到用光光

  ...33,551,61633,551,97633,552,33633,552,696PHP Fatal error: Allowed memory size of 33554432 s exhausted(tried to allocate 16 s) in memleak.php _disibledevent= Foo;$foo->__destruct;un($foo);echo number_format(memory_get_usage) . "n";}?>注意那个新增Foo::__destruct思路方法以及在释放对象前对 $foo->__destruct 现在这段代码解决了内存使用率直增加问题这么来,代码就可以很好工作了

  PHP内核解决方案?

  为什么会有内存溢出发生?我对PHP内核方面研究并不精通但可以确定是此问题和引用计数有关系

  在 $bar 中引用 $foo 引用计数不会父对象 $foo 被释放而递减这时PHP认为你仍需要 $foo 对象也就不会释放这部分内存……大概是这样

  这里确实可以看出我无知但大体意思是:个引用计数没有递减所以些内存永远得不到释放

  在前面提到 bugs.php.net 链接中我看到修改垃圾回收过程将会牺牲极大性能我对引用计数了解不多所以我认为这是真

  和其改变垃圾回收过程为什么不用 un 对内部对象做释放工作呢?(或者在释放对象时候 __destruct?)

  也许PHP内核开发者可以在此或其他地方对这种垃圾回收处理机制做出修改

  更新:Martin Fjordvald 在评论中提到了个由 David Wang 为垃圾回收所写补丁(其实它看起来更像“整块布”——非常巨大详情参见此邮件结尾CVS导出信息)确实存在(封邮件)并受到了PHP内核开发成员关注问题是这个补丁要不要放到PHP5.3中并未得到太多支持我觉得个不错折中方案就是在 un 对象中 __destruct 思路方法;

0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: