捕获(外部)给定回调的内存消耗 [英] Capturing (externally) the memory consumption of a given Callback

查看:95
本文介绍了捕获(外部)给定回调的内存消耗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我说我有这个功能:

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);
}

我想调用它并能够检查它使用的最大内存量.

I would like to call it and be able to inspect the maximum amount of memory it uses.

换句话说: memory_get_function_peak_usage($callback); .这可能吗?

我将以下值用作hog()的非单调递增$i参数:

I'm using the following values as my non-monotonically increasing $i argument for 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()

括起来


Enclosing with 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()的返回值,则结果看起来更加逼真:

If I store the return value of hog(), the results start to look more realistic:

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
)

如预期的那样,现在向我显示返回的内存量,但是我需要使用的总内存.

As expected, now it's showing me the amount of memory returned, but I need the total memory used.

我不知道,但是事实证明,当您这样做时:

I didn't knew, but it turns out that when you do:

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

它不会为hog()函数内部的每一行,语句或代码块打勾,只会为declare块内部的代码打勾-因此,除非在函数中定义了该函数,否则该选项为no去.

It won't tick for every line, statement or block of code inside of hog() function, only for the code inside the declare block - so, unless the function is defined within it, this option is a no go.

我尝试了gc_disable()gc_enable()gc_collect_cycles()的组合(没有太多希望,我必须对上面的两个实验进行试验),以查看是否有任何变化-并没有.

I tried (without much hope I must say) using combinations of gc_disable(), gc_enable() and gc_collect_cycles() with both experiments above to see if anything changed - it didn't.

推荐答案

我正在研究PHP手册,并且发现了

I was digging in the PHP manual and I found the memtrack extension, not perfect but it's something.

编辑:我听说过,但之前从未尝试过.原来我只需要 XHProf :

I had heard about it, but never actually tried it before. Turns out XHProf is all I needed:

$flags = array
(
    XHPROF_FLAGS_CPU,
    XHPROF_FLAGS_MEMORY,
    XHPROF_FLAGS_NO_BUILTINS,
);

$options = array
(
    'ignored_functions' => array
    (
        'call_user_func',
        'call_user_func_array',
        'xhprof_disable',
    ),
);

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);
}


测试#1:

xhprof_enable(array_sum($flags), $options);

hog(4);

$profile = xhprof_disable();

print_r($profile);

输出:

    [main()==>hog] => Array
        (
            [ct] => 1
            [wt] => 54784
            [mu] => 384
            [pmu] => 3142356
        )

    [main()] => Array
        (
            [ct] => 1
            [wt] => 55075
            [mu] => 832
            [pmu] => 3142356
        )

mu是内存使用率,pmu是峰值内存使用率,3142356 / 1024 / 1024 / 0.5 = 4 = $i.

mu is memory usage, pmu is peak memory usage, 3142356 / 1024 / 1024 / 0.5 = 4 = $i.

    [hog==>str_repeat] => Array
        (
            [ct] => 1
            [wt] => 21890
            [cpu] => 4000
            [mu] => 2097612
            [pmu] => 2094200
        )

    [hog==>substr] => Array
        (
            [ct] => 1
            [wt] => 17202
            [cpu] => 4000
            [mu] => 1048992
            [pmu] => 1048932
        )

    [main()==>hog] => Array
        (
            [ct] => 1
            [wt] => 45978
            [cpu] => 8000
            [mu] => 1588
            [pmu] => 3143448
        )

    [main()] => Array
        (
            [ct] => 1
            [wt] => 46284
            [cpu] => 8000
            [mu] => 2132
            [pmu] => 3143448
        )

W!谢谢 Facebook

从XHProf文档中:

From the XHProf docs:

值得说明的是,XHProf并不严格跟踪每个 分配/免费操作.而是使用更简单的方案.它 跟踪分配给PHP的内存量的增加/减少 在每个函数的入口和出口之间.它也跟踪 增加/减少分配给PHP的 peak 内存量 每个功能.

It is worth clarifying that that XHProf doesn't strictly track each allocation/free operation. Rather it uses a more simplistic scheme. It tracks the increase/decrease in the amount of memory allocated to PHP between each function's entry and exit. It also tracks increase/decrease in the amount of peak memory allocated to PHP for each function.

这篇关于捕获(外部)给定回调的内存消耗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆