在调试耗尽内存的代码时,我发现了一个非常有趣的问题,最重要的是我不知道如何解决这个问题。通过引用自身破坏对象
该应用程序大致由单个Survey
对象组成,其中包含多个Question
对象。 Question对象包含对他们所在调查的引用,例如,需要从其他问题获取答案。
下面的循环是造成内存溢出:
foreach ($survey_ids_arr as $survey_id) {
$Survey = new Survey($survey_id);
}
真的没什么异国情调的调查构造正在发生的事情;
- 从数据库
- 从数据库
- 获取的所有问题的属性创建每一个问题一个问题对象获取其属性(传递一个参考$这个)
- 将所有问题对象的内部阵列
并且从查看代码,您会说在每次迭代中,由于$ Survey变量被覆盖,所以对象从内存中清除。对??错误:)
随着脚本经过循环,内存堆积 - 调用显示调查对象使用的内存未按预期释放,此时另一个对象被分配给$Survey
变量。即使在循环结束时调用unset($Survey)
也不会释放内存。
罪魁祸首是传递给在创建问题的对象$this
引用。这些引用防止对象从内存中清除 - 作为php.net状态手册:
析构函数方法将被调用,一旦到某个对象的所有引用都被删除
所以什么阻止对象被清理,是它对自身的引用。很好,嗯? :)
所以,问题是我的对象是一个记忆杀手。不幸的是,我想不出一个解决方案(除了写一个丑陋的方法来清除问题并从循环中调用它)。 Survey中的析构函数不是一个选项;如上所述,这不叫,因为 Question对象仍然有引用。
任何想法?有人必须已经遇到了这个问题 - 含父项的子对象并不是一个不常见的体系结构,是吗?
问题是你的设计中存在一个矛盾:你想阻止对象从内存中清除,但你想清除它? – m0skit0
在php 5.3中解决了这个问题。你使用什么PHP版本? – J0HN
你是对的J0HN,我刚刚发现了错误报告! https://bugs.php.net/bug.php?id=33595 – Rijk