php的引用计数和写时复制

<?php
$a = 1;
xdebug_debug_zval('a');

$b = $a;
xdebug_debug_zval('a');

$a = 2;
xdebug_debug_zval('a');
xdebug_debug_zval('b');

结果以下:php

a: (refcount=1, is_ref=0)=1
a: (refcount=2, is_ref=0)=1
b: (refcount=1, is_ref=0)=2
a: (refcount=1, is_ref=0)=1

过程分析:   bash

1,$a 建立了 引用计数(指向数)为1,非地址引用 而且 值为int类型 1 的 zval容器;
2,新建一个$b,因为是经过赋值的方式将 $a 赋值给 变量$b 的,两个变量所保存的值彻底同样,所以不会申请新内存来存放新变量所保存的值,而是简单的经过一个计数器来共用内存。因此,此时$b也指向 $a 的zval 容器,能够看到引用计数变为了2,仍然是非地址引用;
3,将$a的值赋值为 2,值发生了该表,因为该zval 容器非地址引用,因此系统会从新建立一个 引用计数(指向数)为1,非地址引用而且值为int类型2 的新的zval 容器 指向$a  ,因为 $a 再也不指向原zval容器,因此原容器的 引用计数(指向数) 减 1。spa

总结: 当经过值传递方式进行赋值时,因为两个变量保存的值彻底同样,为了 复用内存,PHP不会为新变量申请新的内存来存放值,而只是在原 zval 容器中将引用计数+1。只有当两个变量中的任何一个变量的值发生改变时,PHP才会从新为发生 值改变 的那个变量申请一个新内存,建立一个新的zval容器。debug

以上内容 就是php内核的一个重要的特性:引用计数写时复制 原理。code

相关文章
相关标签/搜索