PHP5中处理内存消耗的策略?

PHP5中处理内存消耗的策略?,php,memory,Php,Memory,我们有一个大型管理软件,该软件基于大量循环生成各种大型报告,其中包括数据库检索、对象创建(许多)等等 在PHP4上,它可以在64 MB的内存限制下愉快地运行-现在我们已经将它移动到一个新服务器上,使用相同的数据库-相同的代码,没有内存限制就不会出现相同的报告 我知道PHP5在很多方面都发生了变化,但是有没有办法让它正常工作呢 最后的问题是,当您需要节食脚本时,您会采用什么策略?自从移动到新服务器后,您是否验证了MySQL和PHP系统变量与旧服务器上的相同 PHP5引入了许多新功能,但由于其向后兼

我们有一个大型管理软件,该软件基于大量循环生成各种大型报告,其中包括数据库检索、对象创建(许多)等等

在PHP4上,它可以在64 MB的内存限制下愉快地运行-现在我们已经将它移动到一个新服务器上,使用相同的数据库-相同的代码,没有内存限制就不会出现相同的报告

我知道PHP5在很多方面都发生了变化,但是有没有办法让它正常工作呢


最后的问题是,当您需要节食脚本时,您会采用什么策略?

自从移动到新服务器后,您是否验证了MySQL和PHP系统变量与旧服务器上的相同

PHP5引入了许多新功能,但由于其向后兼容的信条,我不认为PHP5和PHP4之间的差异会对应用程序的性能造成如此大的影响,因为应用程序的代码和数据库没有被更改

您是否也在同一版本的Apache或IIS上运行

这听起来更像是一个与您的新系统环境有关的问题,而不是与从PHP4升级到5有关的问题。

Bertrand

如果您对重构现有代码感兴趣,那么我建议您在执行报告时首先监视CPU和内存使用情况。您是锁定了SQL server还是锁定了Apache(如果PHP代码对系统施加了很大压力,就会发生这种情况)

我从事的一个项目最初让MySQL陷入了严重困境,我们不得不重构整个报告生成过程。然而,当我们完成加载时,加载被简单地传输到Apache(通过更复杂的PHP代码)。我们的最终解决方案是重构数据库设计,为报告函数提供更好的性能,并使用PHP弥补MySQL本机无法做到的不足

根据报告的性质,您可以考虑对报告中使用的数据进行非规范化处理。你甚至可以考虑构造一个充当数据仓库的第二个数据库,它是围绕OLAP原理而不是OLTP原理设计的。您可以从Wikipedia开始了解OLAP和数据仓库的一般说明

然而,在开始认真研究重构之前,您是否通过查看phpinfo()验证了您的环境是否足够相似;用于PHP和SHOW变量;
在MySQL中?

我们遇到的一个大问题是对象之间的循环引用阻止它们在超出范围时释放内存


根据您的体系结构,您可以使用_destruct()并手动取消设置任何引用。对于我们的问题,我最终重组了类并删除了循环引用。

当我需要优化任何脚本上的资源时,我总是尝试分析、分析和调试我的代码,我使用,还有其他选项,如和

此外,我建议您阅读以下文章:

  • (PDF)
  • (PDF)
    • 一场演出

      即使64MB也是很大的

      忽略环境之间的差异(听起来确实很奇怪),听起来代码可能需要一些重新分解

      您可以重新考虑代码的因素,以便数据库查询的结果集不会转储到数组中。我建议您为结果集构造一个迭代器。(因此,在大多数情况下,您可以将它们视为数组)。一次处理一条记录与一次处理10000条记录之间有很大的区别


      其次,看看您的代码是否正在创建多个数据实例。你能通过引用传递这些对象吗。(使用“&”)。在使用部落框架的早期变体时,我们必须做类似的事情。一个1MB的附件将从作为副本而不是引用传递整个数据集的多次调用中爆炸到50MB

      PHP5中的对象是通过引用自动传递的。真的吗?!这难道不会挫败范围的概念吗。如果将对象传递给函数,则该函数操作的是对象的副本,而不是实际对象。(除非你通过引用传递对象。)@grantwparks所说的是一个粗略的简化<代码>经常提到的PHP5OOP的一个关键点是“默认情况下对象是通过引用传递的”。这并不完全正确。本节通过一些例子纠正了这种普遍的想法。它不是在对象的副本上操作;如果对传递给函数的对象进行更改,则该对象将更改。创建并传递一个新的“引用/句柄/标识符”(因此根本不传递对象)。该引用使用的内存应该与对象的大小无关。@user1548557称之为总体简化,我称之为寻址内存的实际效果。仅仅因为php.net页面上有很多混乱并不意味着这很复杂。除非你明确地传递一个引用,否则你所建议的行为只会在特定情况下发生,并且不会保留更深层次的对象结构,这不值得争论。php.net文档同意我的观点,您甚至描述了一个进程,承认对象不是通过引用传递的,请查看CS101