写时复制会防止阵列上的数据重复吗?

Posted

技术标签:

【中文标题】写时复制会防止阵列上的数据重复吗?【英文标题】:Will copy-on-write prevent data duplication on arrays? 【发布时间】:2012-06-19 22:59:15 【问题描述】:

我正在用 php 编写一个 Web API 客户端,它将 CSV 数据解析为关联数组,并且我想在使用这些数组时保护我的用户免受数据重复。

我的用户永远不会写入这些数组(理论上可以,但实际上没有意义)。

现在我的问题是......如果我的用户将这些数组作为参数传递给方法,PHP 的写时复制机制是否会防止数据重复,或者任何未明确接受对数组的引用的方法是否会接收数组的完整副本?

【问题讨论】:

【参考方案1】:

如果不更改,则不会复制数组。

【讨论】:

感谢您的及时答复,如果您有时间,如果您能详细说明一下此事,我将不胜感激。接收数组会使用指针吗?或者您能否提供一个链接,指向更多信息以证实您的答案?【参考方案2】:

Copy on write 顾名思义意味着在写入之前不会复制任何变量;只要传递的变量中没有一个字节发生变化,PHP 就会自动避免不必要的重复,并且由于这种机制而无需使用显式引用。

This article详细解释了这是如何在PHP的源代码中实现的,正如文章所建议的,使用xdebug可以很容易地检查变量是否与函数xdebug_debug_zval重复。

此外,this answer 在 SO 上还有更多关于 Copy-on-Write 的内容。

【讨论】:

我还有一个问题。如果你说:$a=array(...); $b=$a; $b[4000].="x"; 会发生什么情况?整个数组会被复制还是只复制索引为 4000 的一个元素? 所以回答我自己的问题,整个数组不会只复制一个索引,你可以用代码看到这一点:php -r '$a=str_repeat("a",1024*1024*1024);$b=str_repeat("b",1024*1024*1024);$a=array($a,$b);$b=$a;$b[1].="x";echo "done\n";sleep(1000000);' 在睡眠时你可以用你最喜欢的系统监视器检查它只使用 3GB 的 ram(如果整个数组被复制,则为 4)。

以上是关于写时复制会防止阵列上的数据重复吗?的主要内容,如果未能解决你的问题,请参考以下文章

我可以在 Linux 中进行写时复制 memcpy 吗?

在Swift结构体中如何实现写时复制?

性能优化之写时复制(Copy-on-write:COW)

Ring3下绕过Windows写时复制机制实现全局EAT钩子

Linux写时复制(CopyOnWrite)|写时拷贝|rcu

利用“写时复制”将数据复制到 Multiprocessing.Pool() 工作进程