con*_*fiq 11 php memory-management
在今天的工作中,我讨论了关于在范围之间传递大数据的拼贴画.神话是,在两个范围之间传递时,引用使用较少的内存/ CPU使用率.我们建立一个合适的概念证明......所以:
function by_return($dummy=null) {
$dummy = str_repeat("1",100 * 1024 * 1024);
return $dummy;
}
function by_reference(&$dummy) {
$dummy = null;
$dummy = str_repeat("1",100 * 1024 * 1024);
}
echo memory_get_usage()."/".memory_get_peak_usage()."\n";
//1 always returns: 105493696/105496656
$nagid = by_return();
echo memory_get_usage()."/".memory_get_peak_usage()."\n";
unset($nagid);
//2 always returns: 105493696/210354184 even if we comment 1st part
by_reference($dummy);
echo memory_get_usage()."/".memory_get_peak_usage()."\n";
unset($dummy);
Run Code Online (Sandbox Code Playgroud)
但似乎通过引用它根据函数"memory_get_peak_usage()"消耗更多内存
如您所见,使用大数据进行返回比使用作为参考要聪明得多,但问题是,为什么?欢迎任何启发:)
小智 9
这是由于php处理变量的方式,并且对于使用C或C++工作的任何人来说都有点违反直觉.
不建议通过引用传递比PHP更聪明.除非需要,否则PHP实际上不会复制数据(即,当对其进行多次引用时更改变量的值),这是一种非常类似于共享内存页面的写时复制的优化策略.
所以,假设你有一个变量,你在给定的脚本中多次传递值.如果你接受这个变量并通过引用传递它,你实际上是复制变量而不是只是获取指向对象的指针.
这是因为在内部,PHP zvals(PHP用于存储变量的数据结构)只能是引用变量或非引用变量.所以zval的ref_count字段是什么并不重要,因为它不是引用变量(zval结构的is_ref字段).因此在内部,PHP被迫创建一个新的zval并将其is_ref字段设置为true,从而使内存加倍.
告诉你的同事不要试图超越PHP.通过引用传递,除非在整个代码中100%完美地完成将导致大量开销并使内存使用量翻倍.
有关更详细的讨论,请参阅此链接:http://porteightyeight.com/2008/03/18/the-truth-about-php-variables/