php中的内存不足错误

问题描述 投票:3回答:3

我在php 5.2.5上,并从命令行执行脚本。在此脚本中,我将处理从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 = ?
php mysql zend-framework memory fetchall
3个回答
1
投票

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

关于为什么不总是回收内存:可能有内存泄漏,但是更有可能的是,PHP的垃圾回收器根本没有立即介入回收内存。您可以尝试使用gc_collect_cycles强制执行gc循环以确认这一点。


0
投票

为了测试,我什至没有存储数据就执行了“ fetchAll”

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

您有明确的closeCursor调用吗?


0
投票

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

gc_collect_cycles
© www.soinside.com 2019 - 2024. All rights reserved.