использование памяти php (true) против верхнего % MEM
У меня есть скрипт, написанный на PHP, который использует API AWS Dynamo PHP. Он выполняет длинный цикл, в котором он извлекает много данных из динамо-машины, а затем обрабатывает их.
Когда я наблюдаю за процессом с помощью "top", я вижу использование памяти, используемое процессом "php"
Внутри цикла моего скрипта я печатаю результат memory_get_usage(true)
Когда я запускаю свой тест, эти два значения даже отдаленно не похожи...
Должны ли они быть такими? Если нет, то почему бы и нет?
В моем тесте я у меня есть сервер с 1,7 Гб оперативной памяти, и я установил для своего php.ini memory_limit 64 МБ. Я также вызываю gc_enable() в начале своего скрипта и между каждым циклом вызываю gc_collect_cycles() в надежде принудительно собрать мусор.
Когда я смотрю свой php-скрипт с использованием "top", я вижу, что %MEM растет и растет, пока в конечном итоге не превысит 95%, и linux убивает процесс php, который я знаю, глядя на "dmesg". Когда я смотрю на распечатки с каждой итерации цикла, использование памяти сообщение memory_get_usage(true) никогда не превышает 50 мб.
Linux считает, что скрипт использует почти 1,7 гб, php считает, что он использует только 50 Мб!
Что происходит?
Даже если в сценарии есть утечки памяти, я не понимаю, почему memory_get_usage(true) не учитывает память...
ОБНОВЛЕНИЕ
Потратив некоторое время на комментирование различных частей обработки, которую я выполняю в своем цикле, я обнаружил, что если я удалю следующее код:
class cMyClass {
public static function static_cmp_fn(&$a, &$b) {
if ($a['att'] == $b['att']) { return 0; }
$ret = ($a['att'] < $b['att']) ? -1 : +1;
return $ret;
}
function DoProcessing(){
$sort_fn = array("cMyClass", "static_cmp_fn");
usort($this->m_dictToSort, $sort_fn);
unset($sort_fn);
}
}
Php никогда не съедает всю системную память. Мне кажется, что у usort происходит утечка памяти, я не знаю почему. Чего я не понимаю, так это почему PHP сообщает неверную информацию о том, сколько памяти он использует...
Есть идеи?
1 answers
Потратив некоторое время на комментирование различных частей обработки, которую я выполняю в своем цикле, я обнаружил, что если я удалю следующий код:
$sort_fn = array("cMyClass", "static_cmp_fn");
usort($this->m_dictToSort, $sort_fn);
Php никогда не съедает всю системную память. Мне кажется, что у usort происходит утечка памяти, я не знаю почему.
По-видимому, так оно и есть. Смотрите руководство:
Http://php.net/manual/en/function.usort.php
"Пара примеров здесь пропагандирует использование "create_function" для сортировки, которую заманчиво использовать из-за ограничений usort. Но остерегайтесь этого метода - созданная функция НЕ будет освобождена в конце процедуры сортировки, что создает утечку памяти. По этой причине этот метод, вероятно, никогда не следует использовать"
.Метод array()
, похоже, делает нечто подобное. Возможно, вы могли бы объявить функцию-оболочку, которая вызывает ваш метод извне?
ОБНОВЛЕНИЕ
Попытался создать небольшой тестовый случай, чтобы увидеть что происходит. Пока я не могу воспроизвести утечку; возможно, с большим количеством данных о том, что static_cmp_fn()
делает и как m_dictToSort
структурировано. Простое сравнение не вызывает ничего странного. Равно как и выделение строк, массивов или объектов внутри цикла. Сборщик мусора убивает их, и память остается низкой.
Я бы еще больше ограничил проблему, вызвав другую функцию , которая вообще не сортирует или выполняет очень простую сортировку, чтобы увидеть, заключается ли проблема в том, что usort
делает что-то забавное с его возможностью вызова, как я и думал (похоже, это не так, и я ошибался), или если внутри функции сравнения происходит что-то забавное.