Это может быть лучше подходит для отказа сервера, но я подумал, что сначала спрошу здесь.
У нас есть файл, который добавляется к каждому файлу PHP на наших серверах, используя auto-prepend, который содержит класс под названием Bootstrap
, который мы используем для автозагрузки, обнаружения среды и т.д. Все это работает нормально.
Однако, когда есть ошибка "OUT OF MEMORY", непосредственно предшествующая (т.е. менее секунды или даже в то же время) запрос на другой файл на том же сервере, происходит одна из трех вещей:
-
Наш код для проверки
if(class_exists('Bootstrap')
, который мы использовали для обертывания определения класса, когда мы впервые получили эту ошибку, возвращаетtrue
, что означает, что класс уже был объявлен, несмотря на то, что это файл автопредложения. -
Мы получаем ошибку "not not redeclare class Bootstrap" из нашего автоматически добавленного файла, а это означает, что
class_exists('Bootstrap')
возвращенfalse
, но он каким-то образом был объявлен. - Файл не добавляется вообще, что приводит к одноразовой фатальной ошибке для файлов, которые зависят от нее.
Мы могли бы, конечно, попытаться устранить проблемы с памятью, поскольку они, похоже, вызывают другие ошибки, но по разным причинам они не могут быть исправлены в нашей установке или очень трудно исправить. Но, кроме того, мне кажется, что это ошибка в PHP с какой-то утечкой памяти, вызывающей проблемы с директивой auto-prepend.
Это больше любопытства, чем что-либо, поскольку это редко случается (может быть, раз в неделю на наших серверах с высоким трафиком). Но я хотел бы знать, почему это происходит, и что мы можем сделать, чтобы исправить это?
Мы запускаем FreeBSD 9.2 с PHP 5.4.19.
EDIT: несколько вещей, которые мы заметили, пытаясь исправить это за последние несколько месяцев:
-
Кажется, это происходит только на наших защищенных серверах. Проблемы с отсутствием памяти в основном на наших защищенных серверах (обычно из наших собственных сотрудников, пытающихся загрузить слишком много данных), поэтому это может быть просто совпадение, но заслуживает внимания
-
Дамп
get_declared_classes
, когда у нас есть эта проблема, содержит классы, которые не используются на странице, вызывающей ошибку. Например, вывод$_SERVER
говорит, что человек находится на xyz.com, но один из объявленных классов используется только на abc.com, из которого обычно возникают проблемы с памятью. -
Все это заставляет меня поверить, что PHP не делает правильную сборку мусора в конце цикла после получения ошибки из памяти, что приводит к тому, что класс
Bootstrap
должен быть полностью или частично в памяти на следующий запрос страницы, если он достаточно скоро после ошибки. Я недостаточно разбираюсь в сборке мусора PHP, чтобы на самом деле воздействовать на это, но я думаю, что это, скорее всего, проблема.