использование памяти 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 сообщает неверную информацию о том, сколько памяти он использует...

Есть идеи?

Author: sungiant, 2012-09-28

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 делает что-то забавное с его возможностью вызова, как я и думал (похоже, это не так, и я ошибался), или если внутри функции сравнения происходит что-то забавное.

 1
Author: LSerni, 2012-09-28 14:20:59