PHP 5.5.6 随机内存泄漏
PHP 5.5.6 Random memory leak
在我们从 PHP 5.3.3
迁移到 PHP 5.5.6
和 Apache 2.4
之后,在 Kohana 3.3
上运行的每个站点都会遇到计时 Out of memory
异常。
完整的错误信息
PHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 140316914598360 bytes) in Unknown on line 0
PHP 表示它尝试分配 127TB
内存(末尾的字节发生变化,但仍在 TB 左右)。它完全随机发生。有时您会连续几个小时没有问题,然后突然连续出现 1 条甚至 10 条内存不足消息。它发生在所有项目中,无论是连接到 MySQL、MSSQL 或 MongoDB 还是普通网站的 Web 服务。
最糟糕的是这个 - Unknown on line 0
这告诉我 什么都没有 。即使禁用已注册的 shutdown_function
,消息也没有改变。
起初我怀疑 PDO dblib + freetds
是罪魁祸首,但使用 while($row = $query->fetch())
没有任何进展,如 https://bugs.php.net/bug.php?id=64511 or this question 中所述。
到目前为止我已经尝试过:
- xdebug
- memory_usage() 日志记录
- httpd 上的 strace
它们都表明内存分配处于完美状态。
只有 strace
显示了一些承诺,因为在每个 out of memory
异常抛出之前,是一堆 munmap
调用,这表明内存不断减少然后突然抛出异常.虽然我不确定它是否可靠,因为日志有时看起来很混杂(来自不同的调用)。
有没有人遇到过类似的事情?
调试此问题的最佳步骤是什么?
目前,我不知道该如何解决这个问题...
我将自己回答这个问题,以备将来参考。
毕竟真正的错误在 pdo_dblib
中。根据这个错误 - https://bugs.php.net/bug.php?id=67130 我昨天发现 PDOStatement::nextRowset()
导致内存损坏,从而导致我们所有的问题。我通过删除我们代码的这一部分并让它 运行 在 "rush" 流量中持续 12 小时来验证它。
此错误已与 https://bugs.php.net/bug.php?id=64511 一起修复,起初我没有注意到这两者是相关的。
我们在 CentOS 上的系统 运行s 和 PHP 是从 Software Collections 安装的,因此我们下载了所述模块的源代码并手动应用了补丁,因为同一软件包的两个版本来自 Remi 的RPM 存储库不工作或不兼容。
这真的很有趣,因为我们从 5.3.3
迁移到 5.5.6
因为 https://bugs.php.net/bug.php?id=57593(有几个错误报告和功能请求)其中 PDOStatement::nextRowset()
没有实现(已在 5.3.7 中修复)。
在我们从 PHP 5.3.3
迁移到 PHP 5.5.6
和 Apache 2.4
之后,在 Kohana 3.3
上运行的每个站点都会遇到计时 Out of memory
异常。
完整的错误信息
PHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 140316914598360 bytes) in Unknown on line 0
PHP 表示它尝试分配 127TB
内存(末尾的字节发生变化,但仍在 TB 左右)。它完全随机发生。有时您会连续几个小时没有问题,然后突然连续出现 1 条甚至 10 条内存不足消息。它发生在所有项目中,无论是连接到 MySQL、MSSQL 或 MongoDB 还是普通网站的 Web 服务。
最糟糕的是这个 - Unknown on line 0
这告诉我 什么都没有 。即使禁用已注册的 shutdown_function
,消息也没有改变。
起初我怀疑 PDO dblib + freetds
是罪魁祸首,但使用 while($row = $query->fetch())
没有任何进展,如 https://bugs.php.net/bug.php?id=64511 or this question 中所述。
到目前为止我已经尝试过:
- xdebug
- memory_usage() 日志记录
- httpd 上的 strace
它们都表明内存分配处于完美状态。
只有 strace
显示了一些承诺,因为在每个 out of memory
异常抛出之前,是一堆 munmap
调用,这表明内存不断减少然后突然抛出异常.虽然我不确定它是否可靠,因为日志有时看起来很混杂(来自不同的调用)。
有没有人遇到过类似的事情?
调试此问题的最佳步骤是什么?
目前,我不知道该如何解决这个问题...
我将自己回答这个问题,以备将来参考。
毕竟真正的错误在 pdo_dblib
中。根据这个错误 - https://bugs.php.net/bug.php?id=67130 我昨天发现 PDOStatement::nextRowset()
导致内存损坏,从而导致我们所有的问题。我通过删除我们代码的这一部分并让它 运行 在 "rush" 流量中持续 12 小时来验证它。
此错误已与 https://bugs.php.net/bug.php?id=64511 一起修复,起初我没有注意到这两者是相关的。
我们在 CentOS 上的系统 运行s 和 PHP 是从 Software Collections 安装的,因此我们下载了所述模块的源代码并手动应用了补丁,因为同一软件包的两个版本来自 Remi 的RPM 存储库不工作或不兼容。
这真的很有趣,因为我们从 5.3.3
迁移到 5.5.6
因为 https://bugs.php.net/bug.php?id=57593(有几个错误报告和功能请求)其中 PDOStatement::nextRowset()
没有实现(已在 5.3.7 中修复)。