内存不足错误后,PHP会自动添加错误

jra*_*ede 14 php garbage-collection freebsd out-of-memory

这可能更适合服务器故障,但我想我先问这里.

我们的服务器上的每个PHP文件都有一个文件,它使用auto-prepend,它包含一个Bootstrap我们用于自动加载,环境检测等的类.它一切正常.

但是,当在同一服务器上的另一个文件的请求之前(即,小于一秒或甚至同时)存在"OUT OF MEMORY"错误时,会发生以下三种情况之一:

  1. 我们用于检查的代码(if(class_exists('Bootstrap')我们在第一次遇到此错误时用于包装类定义)返回true,这意味着该类已经被声明,尽管这是自动前置文件.

  2. 我们从自动预装文件中得到"无法重新声明类Bootstrap"错误,这意味着class_exists('Bootstrap')返回false但仍以某种方式仍然声明了.

  3. 该文件根本没有预先设置,导致依赖于它的文件出现一次性致命错误.

当然,我们可以尝试修复内存不足问题,因为这些问题似乎导致了其他错误,但由于各种原因,它们在我们的设置中无法修复或者很难修复.但这不是重点 - 在我看来,这是PHP中的一个错误,某种内存泄漏会导致auto-prepend指令出现问题.

这比任何事情都更好奇,因为这很少发生(可能每周一次在我们的高流量服务器上).但我想知道 - 为什么会发生这种情况,我们可以采取哪些措施来解决这个问题?

我们正在运行FreeBSD 9.2使用PHP 5.4.19.

编辑:我们在过去几个月试图解决这个问题时注意到的一些事情:

  • 它似乎只发生在我们的安全服务器上.内存不足问题主要出现在我们的安全服务器上(他们通常是我们自己的员工试图下载过多的数据),所以这可能只是巧合,但值得指出

  • get_declared_classes我们遇到此问题时的转储包含未在触发错误的页面上使用的类.例如,该$_SERVER人的输出在xyz.com上,但其中一个声明的类仅用于abc.com,这是内存不足问题通常源自的地方.

  • 所有这一切使我相信PHP在获得内存不足错误后没有进行正确的循环结束垃圾收集,这导致Bootstrap类在下一页请求中完全或部分在内存中,如果它很快就会错误.我不熟悉PHP垃圾收集实际上对此采取行动,但我认为这很可能是问题所在.

Ozz*_*zzy 0

即使class_exists返回 false,如果存在同名接口,也永远不会返回 true。但是,您不能声明同名的接口和类。

尝试运行class_exists('Bootstrap') && interface_exists('Bootstrap')以确保您不会重新声明。