捕获(外部)给定回调的内存消耗 [英] Capturing (externally) the memory consumption of a given Callback
问题描述
让我说我有这个功能:
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.
推荐答案
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屋!