php中COW机制(转)
原文:https://blog.csdn.net/qq_38253837/article/details/80340505
COW(copy on write) 写时复制,是内存优化的常见手段,在php中也采用了这种方式来优化内存。
即只有当对其中一个或多个变量进行写操作的时候,才会复制一份内存,对其内容进行修改。
下面看一个例子
copy<?php
echo '程序开始时内存的使用情况:';
var_dump(memory_get_usage());
//定义一个变量a
$a = range(0, 9);
echo '定义变量a后内存的使用情况:';
var_dump(memory_get_usage());
//定义一个变量b,将变量a的值赋值给b
$b = $a; //使用相同的内存
echo '定义了变量b,将变量a的值赋值给b后,内存的使用情况:';
var_dump(memory_get_usage());
echo '修改a的值后,内存的使用情况:';
$a = range(9, 0);
var_dump(memory_get_usage());
代码运行结果:
可以看出,在定义了变量a后,内存的使用量为359888,当定义变量b,并将变量b的值初始化为变量a,此时,php给程序分配的内存并没有发生改变!说明变量a和b使用同一块内存空间,当给变量a重新赋值时,即修改变量a的值后,发现内存量有所增加,从而验证了php中COW机制。
引用是比较特殊的,下面我们再来看一下,直接看栗子吧~
copy<?php
echo '程序开始时内存的使用情况:';
var_dump(memory_get_usage());
//定义一个变量a
$a = range(0, 9);
echo '定义变量a后内存的使用情况:';
var_dump(memory_get_usage());
//定义一个引用变量b,将变量a的值赋值给b
$b = &$a;
echo '定义了变量b,将变量a的值赋值给b后,内存的使用情况:';
var_dump(memory_get_usage());
echo '修改a的值后,内存的使用情况:';
$a = range(9, 0);
var_dump(memory_get_usage());
代码运行结果:
与上段代码不同的是,变量b声明为a的引用,在定义变量b之后,程序所占的内存增加的很好,并没有定义a时增加的多,由此可以看出,并没有为变量单独分配内存,因为在php中,引用是用不同的名字访问相同的变量内容(变量和变量内容是不同的概念),在修改变量a的值后,改变的是两个变量名指向的共同的变量内容,所以并没有内存的增加。我们再来看一下使用xdebug调试一下,代码修改后如下:
copy<?php
//定义一个变量a
$a = range(0, 9);
echo '定义变量a后:<br />';
xdebug_debug_zval('a');
//定义一个引用变量b,将变量a的值赋值给b
$b = &$a;
echo '定义了变量b,将变量a的值赋值给b后:<br />';
xdebug_debug_zval('b');
echo '修改a的值后:<br />';
$a = range(9, 0);
xdebug_debug_zval('b');
代码运行结果:
由此可得:定义了a的引用b后,refcount的值为2,即使修改了a的值,引用数并没有减少,只是两个变量名指向的共同的变量内容的值发生了改变。由于引用是共用一块变量内容,所以即使是通过其中一个变量名修改变量内容的值,也不会发生内存的复制。
COW是优化内存的一种手段,是的值相同的变量可以共用同一块内存,从而减少了内存的分配,提高了内存的使用率。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构