Недавно я столкнулся с той же проблемой, к сожалению, не смог найти никаких конкретных инструментов.
Но кое-что, что помогло, заключалось в том, чтобы вывести трассировку xdebug в удобочитаемом формате с включенными дельтами памяти (настройка INI, xdebug.show_mem_deltas или что-то в этом роде, я думаю?). Затем запустите sort (если вы используете * nix) на выходе:
sort -bgrk 3 -o sorted.txt mytracefile.xt
Это сортировка по третьему столбцу, mem deltas. Вы также можете отсортировать по второму столбцу, и в этом случае вы можете найти строку, в которой ваше приложение использует больше всего памяти в целом.
Конечно, это не может определить, когда использование памяти объектом только увеличивается небольшими приращениями, но в конечном итоге использует большой объем памяти в целом. У меня есть довольно глупый метод, который пытается сделать это, используя комбинацию итерации объекта и сериализации. Это, вероятно, не совсем соответствует использованию памяти, но, надеюсь, дает представление о том, с чего начать. Имейте в виду, что он сам будет использовать память, а также не был тщательно протестирован, поэтому покупатель остерегается:
function analyzeMem($obj, $deep=false)
{
if (!is_scalar($obj))
{
$usage = array('Total'=>strlen(serialize($obj)));
while (list($prop, $propVal) = each($obj))
{
if ($deep && (is_object($propVal) || is_array($propVal)))
{
$usage['Children'][$prop] = analyzeMem($propVal);
}
else
{
$usage['Children'][$prop] = strlen(serialize($propVal));
}
}
return $usage;
}
else
{
return strlen(serialize($obj));
}
}
print_r(analyzeMem(get_defined_vars()));
Кроме того, коллега только что предложил этот метод (приветствует Денниса ;-) Он скрывает шаги, которые находятся ниже двух уровней отступа, вы можете довольно легко увидеть точки, в которых общее использование памяти подскакивает, и можете сузить круг, увеличив отступ:
egrep '[0-9]+ ( ){1,2}-> ' mytracefile.xt
person
EvilPuppetMaster
schedule
01.12.2008