Итак, у меня очень странная проблема.
Во-первых, я использую PHP 5.2.6 (как часть MAMP, хотя это также происходит на сервере LAMP под управлением 5.2.6), пишу веб-сайт с использованием Zend Framework 1.7.2.
Во-вторых, программное обеспечение, которое я пишу, выполняет довольно сложный статистический расчет, который требует много памяти. Обычно он работает нормально с ограничением памяти в 128 МБ.
Итак, вот самое интересное.
У меня есть класс, который отвечает исключительно за получение необходимых данных, выполнение необходимых вычислений и возврат значений. После того, как он запустился, я отключил его, так как PHP, кажется, думает, что он все еще находится в области видимости и удерживает память для него, несмотря на завершение функции, в которой он вызывается (это вызывало проблемы, когда второй прогон вычисления был удар по пределу памяти и скрипт умер). После того, как этот расчет выполняется один раз внутри этой функции, он снова запускается в другой функции для выполнения другого вычисления (это происходит во время того же самого выполнения). Вот где все становится странным.
Если я выполню это второе вычисление, вызывающая функция снова запустится, несмотря на то, что в коде, выполняющем это вычисление, нет абсолютно никаких вызовов этой функции. Также в PHP не появляются ошибки или предупреждения.
Однако, если я увеличу предел памяти (скажем, до 1024 МБ), этого не произойдет. Общая вызывающая функция запускается один раз и продолжает свой веселый путь.
Итак, позвольте мне нарисовать карту ниже.
function A{
calls function B
calls function D
}
function B{
calls calculation function C
}
function D{
calls calculation function C
}
с 128 МБ памяти, путь функций следующий (внутри и обратно к вызывающей стороне):
A-> B-> C-> B-> A-> D-> C-> D-> затем он запускает A от начала функции, по какой-то причине, до конца (есть условный случай, который становится истинным во время этого пути выполнения, поэтому путь не повторяется)
с 1 ГБ памяти, путь функций следующий:
A-> B-> C-> B-> A-> D-> C-> D-> конец A, что и должно быть.
Если я уберу второе вычисление из функции D, оно сработает. Если у меня до предела памяти, это работает.
Вопрос: нашел ли я ошибку в управлении памятью PHP? Или, может быть, в Zend Framework? Снова; Увеличивая лимит памяти на скрипт в php.ini, я не вижу этой проблемы. Или удалите второй экземпляр этого вычисления, который использует много памяти.
Я очень, очень уверен, что так оно и происходит, несмотря на странность того, как это происходит (я никогда не видел такого рода прыжков назад к началу вызывающей функции). Обычно в этом случае происходит то, что PHP выдаст ошибку и умрет, а не перезапустит вызывающую функцию.