Захват (извне) потребления памяти данным обратным вызовом

Проблема

Допустим, у меня есть эта функция:

function hog($i = 1) // uses $i * 0.5 MiB, returns $i * 0.25 MiB
{
    $s = str_repeat('a', $i * 1024 * 512); return substr($s, $i * 1024 * 256);
}

Я хотел бы позвонить и проверить максимальный объем используемой памяти.

Другими словами:memory_get_function_peak_usage($callback);, Это возможно?

Что я попробовал

Я использую следующие значения в качестве моего немонотонно увеличивающегося$i аргумент в пользуhog():

$iterations = array_merge(range(0, 50, 10), range(50, 0, 5));
$iterations = array_fill_keys($iterations, 0);

Что по сути:

(
    [0] => 0
    [10] => 0
    [20] => 0
    [30] => 0
    [40] => 0
    [50] => 0
    [45] => 0
    [35] => 0
    [25] => 0
    [15] => 0
    [5] => 0
)
Вложение сmemory_get_usage()
foreach ($iterations as $key => $value)
{
    $alpha = memory_get_usage(); hog($key);
    $iterations[$key] = memory_get_usage() - $alpha;
}

print_r($iterations);

Выход:

(
    [0] => 96
    [10] => 0
    [20] => 0
    [30] => 0
    [40] => 0
    [50] => 0
    [45] => 0
    [35] => 0
    [25] => 0
    [15] => 0
    [5] => 0
)

Если я храню возвращаемое значениеhog()результаты начинают выглядеть более реалистично:

foreach ($iterations as $key => $value)
{
    $alpha = memory_get_usage(); $s = hog($key);
    $iterations[$key] = memory_get_usage() - $alpha; unset($s);
}

print_r($iterations);

Выход:

(
    [0] => 176
    [10] => 2621536
    [20] => 5242976
    [30] => 7864416
    [40] => 10485856
    [50] => 13107296
    [45] => 11796576
    [35] => 9175136
    [25] => 6553696
    [15] => 3932256
    [5] => 1310816
)

Как и ожидалось, теперь он показывает мне количество памятивозвращенный, но мне нужно общее количество используемой памяти.

С помощьюregister_tick_function():

Я не знала, но получается, что когда вы делаете:

declare (ticks=1)
{
    $a = hog(1);
}

Это не будет отмечаться для каждой строки, оператора или блока кода внутриhog() функция, только для кода внутриdeclare block - поэтому, если функция не определена внутри него, эта опция не нужна.

Смешивание сgc_* функции:

Я пытался (без особой надежды, я должен сказать), используя комбинацииgc_disable(), gc_enable() а такжеgc_collect_cycles() с обоими экспериментами выше, чтобы видеть, изменилось ли что-нибудь - это не сделало.

Ответы на вопрос(3)

Ваш ответ на вопрос