php中的内存不足错误

时间:2012-11-05 09:41:02

标签: php mysql zend-framework memory fetchall

我在php 5.2.5上并从命令行执行脚本。在这个脚本中,我正在操作从db获取的数据。要从db获取数据我正在使用Zend Adapter。 我注意到在调用后内存增加(262144字节)  “fetchAll($ sql,$ data,Zend_Db :: FETCH_ASSOC)”

因此最终导致内存不足。 测试我刚刚执行了“fetchAll”,甚至没有将它返回的数据存储在任何变量中。但我仍然看到内存增加,而不是回收。

  • Zend FetchAll方法是否存在内存泄漏问题?
  • 为什么内存增加262144或者是262144的倍数?
  • 内存增加是随机发生的,而不是在所有fetchAll调用中,为什么会这样?

我已经尝试使用memory_get_usage()来确定内存泄漏的原因,但由于代码很大,需要花费很多时间,有什么方法可以获取内存中所有对象的详细信息以便我可以更好地调试问题吗?

sql是: -

select b.Id as Id,b.Lang 
from groups g 
left join table1 b on b.Group_Id = g.Id 
left join table2 bs on bs.Id = b.Id 
where g.Id = ? and b.Lang = ?

3 个答案:

答案 0 :(得分:1)

要立即返回所有结果,必须将它们存储在内存中的数组中。即使您没有将结果分配给任何变量,fetchAll内部仍然必须构建该数组。如果有太多结果一次存储在内存中,你将耗尽内存;非常简单。

至于为什么内存并不总是被回收:可能是内存泄漏,但更有可能的是PHP的垃圾收集器不会立即启动来回收内存。您可以尝试使用gc_collect_cycles强制执行gc循环来确认。

答案 1 :(得分:0)

  

测试我刚刚执行了“fetchAll”而没有存储数据

但是你已经存储了2份数据。大多数数据库客户端将维护服务器返回的数据缓冲区(在mysql的情况下,它具有完整的数据集)。当你调用fetchAll()时,整个数据集被检索到缓冲区(如果它还没有)然后将它映射到PHP数组。

你有一个明确的closeCursor电话吗?

答案 2 :(得分:0)

您可以逐行获取结果,而无需将其加载到内存中:

   /**
    * @var $select \Zend_Db_Select
    **/
    if ($stmt = $select->query()) {
        while ($row = $stmt->fetch()) { //... }
    }