我在php 5.2.5上,并从命令行执行脚本。在此脚本中,我将处理从db获取的数据。为了从数据库获取数据,我正在使用Zend Adapter。我在调用后发现内存增加(262144字节)“ fetchAll($ sql,$ data,Zend_Db :: FETCH_ASSOC)”
因此最终导致内存不足。为了测试,我只执行了“ 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 = ?
要立即返回所有结果,必须将它们存储在内存中的数组中。即使您未将结果分配给任何变量,fetchAll
在内部仍必须构建该数组。如果有太多结果要立即存储在内存中,则将耗尽内存。非常简单。
关于为什么不总是回收内存:可能有内存泄漏,但是更有可能的是,PHP的垃圾回收器根本没有立即介入回收内存。您可以尝试使用gc_collect_cycles
强制执行gc循环以确认这一点。
为了测试,我什至没有存储数据就执行了“ fetchAll”
但是您已经存储了2个数据副本。大多数数据库客户端将维护服务器返回的数据缓冲区(对于mysql,它具有完整的数据集)。当您调用fetchAll()时,整个数据集将被检索到缓冲区(如果尚不存在)和然后将其映射到PHP数组。
您有明确的closeCursor调用吗?
您可以逐行获取结果,而无需将其加载到内存中:
gc_collect_cycles