PHP写时复制(Copy-on-Write)
2014-04-21 00:00
771 查看
说到PHP的垃圾回收机制引用计数器和写时复制是不得不说的,引用计数器就是让写时复制正常工作的保证,它们是PHP的主要优化手段。【推荐阅读PHP引用计数器】
在教程之前,希望大家能够完全理解zval变量容器中的ref_count和is_ref
is_ref标识是不是用户使用 & 的强制引用;
ref_count是引用计数,用于标识此zval被多少个变量引用,即COW的自动引用,为0时会被销毁;
写时复制(Copy-on-Write)概念:
简单的理解就是资源延时分配,如下代码:
PHP中的变量是用一个存储在symbol_table中的符号名,对应一个zval来实现的,比如对于上面的第一行代码,会在symbol_table中存储一个值”a”, 对应的有一个指针指向一个zval结构,变量值“1”会被保存在zval中,实际上$a和$b都是指向同一个zval就实现了节省资源的目的,特点是在大数组复制等场景下会节省很多内存,但变量的值一旦发生变化,指向的zval就是变化。
写时复制(Copy-on-Write)实现:
于是就引入了is_ref和ref_count两个标志,看下面简单代码:
如果改变一个变量的值呢?
PHP在修改一个变量以前,会首先查看这个变量的refcount,如果refcount大于1,PHP就会执行分离,如上,PHP发现$a指向的zval的refcount大于1,那么PHP就会复制一个新的zval出来,将原zval的refcount减1,并修改symbol_table,使得$a和$b分离(Separation)。这个机制就是所谓的copy on write(写时复制)。
看一个复杂点的ref_count和is_ref变化的例子:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201502/cdb6615e5c3de4f76051d181d02e5fb5.png)
参考资料:
(1)PHP手册:http://www.phpddt.com/manual/php/res/features.gc.refcounting-basics.html
(2)http://www.php-internals.com/book/?p=chapt06/06-06-copy-on-write
(3)http://www.laruence.com/2008/09/19/520.html
在教程之前,希望大家能够完全理解zval变量容器中的ref_count和is_ref
is_ref标识是不是用户使用 & 的强制引用;
ref_count是引用计数,用于标识此zval被多少个变量引用,即COW的自动引用,为0时会被销毁;
写时复制(Copy-on-Write)概念:
简单的理解就是资源延时分配,如下代码:
<?php $a = 1; $b = $a;
PHP中的变量是用一个存储在symbol_table中的符号名,对应一个zval来实现的,比如对于上面的第一行代码,会在symbol_table中存储一个值”a”, 对应的有一个指针指向一个zval结构,变量值“1”会被保存在zval中,实际上$a和$b都是指向同一个zval就实现了节省资源的目的,特点是在大数组复制等场景下会节省很多内存,但变量的值一旦发生变化,指向的zval就是变化。
写时复制(Copy-on-Write)实现:
于是就引入了is_ref和ref_count两个标志,看下面简单代码:
$a = 1; //为什么是2呢?当执行debug_zval_dump($var)的时候, //$var会以传值的方式传递给debug_zval_dump,也就是会导致var的refcount加1 debug_zval_dump($a); //long(1) refcount(2) $b = $a; //必然的是:当一个变量复制给另一个变量会导致zval的recount加1 debug_zval_dump($a); //long(1) refcount(3)
如果改变一个变量的值呢?
$a = 1; //为什么是2呢?当执行debug_zval_dump($var)的时候, //$var会以传值的方式传递给debug_zval_dump,也就是会导致var的refcount加1 debug_zval_dump($a); //long(1) refcount(2) $b = $a; //必然的是:当一个变量复制给另一个变量会导致zval的recount加1 debug_zval_dump($a); //long(1) refcount(3)
$a = 'http://www.phpddt.com';
debug_zval_dump($a); // string(21) "http://www.phpddt.com" refcount(2)
debug_zval_dump($b); //long(1) refcount(2)
PHP在修改一个变量以前,会首先查看这个变量的refcount,如果refcount大于1,PHP就会执行分离,如上,PHP发现$a指向的zval的refcount大于1,那么PHP就会复制一个新的zval出来,将原zval的refcount减1,并修改symbol_table,使得$a和$b分离(Separation)。这个机制就是所谓的copy on write(写时复制)。
看一个复杂点的ref_count和is_ref变化的例子:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201502/cdb6615e5c3de4f76051d181d02e5fb5.png)
参考资料:
(1)PHP手册:http://www.phpddt.com/manual/php/res/features.gc.refcounting-basics.html
(2)http://www.php-internals.com/book/?p=chapt06/06-06-copy-on-write
(3)http://www.laruence.com/2008/09/19/520.html
相关文章推荐
- PHP源码分析-变量的引用计数、写时复制(Reference counting & Copy-on-Write)
- PHP 之 写时复制介绍(Copy On Write)
- PHP写入时复制 (Copy on Write)
- PHP中copy on write写时复制机制介绍
- PHP中的写时复制(Copy On Write)
- php源码之路第六章第五节 ( 写时复制(Copy On Write))
- PHP 之 写时复制介绍(Copy On Write)
- PHP写时复制(Copy On Write)
- PHP中copy on write写时复制机制介绍
- QVector与QByteArray——Qt的写时复制(copy on write)技术
- 写时复制Copy-On-Write
- 从win32中的写时复制(Copy on write )机制谈起
- 数组指针特例-写时复制cow(copy on write)
- 关于 copy-on-write 写时复制
- 浅析mfc的Cstring类的copy-on-write(写时复制)功能
- Copy-On-Write 写时复制原理
- copy-on-write 写时复制
- JAVA中写时复制(Copy-On-Write)Map实现
- Copy-On-Write(写入时复制)技术
- 写时复制(copy-on-write)