【问题标题】:Decent memory profiling tool for php不错的 php 内存分析工具
【发布时间】:2025-12-20 22:20:17
【问题描述】:

我使用 SendGrid 官方 PHP 库和 SMTP API 构建了一个自动邮件应用程序(自动邮件程序在 Ubuntu 服务器上作为 cron 作业运行)。

生产服务器上的内存限制设置为 32M,但在生产服务器上第一次运行应用程序时,我收到了消息

已用尽允许的 33554432 字节内存大小,试图分配 256478 字节

从 256478

根据to this post,PHP 存在内存泄漏问题,在处理对象之间的相互关系时,我使用自己的 Wrapper 类,以使代码更具可读性和结构化,主 mailService 类,以及每个类任务,实现一个接口,并返回每封电子邮件的所有特定数据(标题、子值、收件人列表)。

我将首先向我的接口和每个类添加一个析构函数,以确保没有内存泄漏,但我不确定这是否能解决问题,因为根据我的内存基准测试已经执行了,大部分执行时间,内存被SwiftMailer的MailTransport.php类消耗掉了。

所以我的问题基本上是,如何在每次迭代时重置这个类的内存使用量?是否有内置的东西,或者我应该自己实现这样的方法?

非常感谢任何帮助。

小可视化:

【问题讨论】:

  • 您是否正在构建所有电子邮件收件人的列表?这很容易成为内存占用者,尤其是在 32M 限制较低的情况下
  • 嗯,每个特定任务仅适用于某些用户,NotifyTokenExpiry 仅适用于其令牌在过去一个月内过期的用户,topScores 仅适用于排名积极的用户等等,并且在在每次迭代结束时,我 unset() 保存收件人列表的成员,并在之后为其分配一个空值以确保。无论如何,您必须有相当数量的电子邮件才能超过 32M 的限制,我只测试了我的应用程序,邮件数量低于 500 封

标签: php memory-management memory-leaks


【解决方案1】:

允许的内存大小 33554432 字节已用尽,试图分配 256478 字节

意味着 PHP 正在尝试分配一个 additional 256478,超出它在脚本运行期间已经分配的内容,并且 additional 请求是推送的内容超过 33554432 阈值的总内存使用量。

早期版本的 PHP 在遇到对象之间的循环引用时会出现内存问题,尽管 5.4 对此有所改善...。您是否受到影响将取决于您正在运行的 PHP 版本,以及您的类是否实际包含此类循环引用

【讨论】:

  • 我正在运行 PHP 5.4,如何跟踪和修复可能的内存泄漏?对我来说,当应用程序所做的所有事情都是发送电子邮件时,它似乎不太可能消耗这么大量的内存。感谢您的回复!
  • 正如我之前提到的,如果您正在为您的电子邮件建立一个收件人列表,这可能会消耗内存 - 但 32MB 用于 PHP 及其所有模块以及您的脚本
  • 我算了一下,我的电子邮件模板重量为 8 KB,每种电子邮件类型加载一次,电子邮件收件人列表由一个常规键 => val 数组组成,其中包含
  • 关于使用 xdebug 跟踪内存使用情况的说明 -geek.michaelgrace.org/2012/04/… - 适用于 mac 上的 mamp,但应该适用于所有平台
  • 谢谢,但不幸的是,我运行的是 Ubuntu 12.10,并且使用的是 Sublime 2 IDE。
【解决方案2】:

PHP 自 5.3 起具有garbage collection 功能,您可以尝试使用它来查看它是否有助于您的特殊情况。另见this other SO question

【讨论】: