3

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

因此最终导致内存不足。为了测试,我只是执行了“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 = ?
4

3 回答 3

1

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

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

于 2012-11-05T09:58:52.890 回答
0

为了测试我只是执行了“fetchAll”,甚至没有存储数据

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

你有明确的 closeCursor 调用吗?

于 2012-11-05T12:56:08.540 回答
0

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

   /**
    * @var $select \Zend_Db_Select
    **/
    if ($stmt = $select->query()) {
        while ($row = $stmt->fetch()) { //... }
    }
于 2020-02-05T01:09:16.860 回答