本篇文章是对PHP中的引用计数机制进行了详细的分析介绍,需要的朋友参考下
PHP的变量声明并赋值后,变量名存在符号表中,而值和类信息存在zval中,zval中包含四个变量,is_ref,refcount,value,type,zval源码如下
复制代码 代码如下:
struct _zval_struct {
/* Variable information */
zvalue_value value;
/* value */
zend_uint refcount__gc;
zend_uchar type; /* active type */
zend_uchar is_ref__gc;
};
此处分析一下什么时候zval会被复制或者开辟新的内存空间呢
1.当is_ref=0,且refcount>1时,如果改变某个指向该zval的变量的值,会生成新zval,原zval的refcount--,例如:$a=1;$b=$a;$b=2;,zval将被复制,也就是说原先ab指向同一个zval,香港虚拟主机,后来b会使用新开辟的zval
2.当is_ref=0,且refcount>1时,如果将zval赋值给某个引用变量,香港虚拟主机,那么用来赋值和变量和被赋值的变量会使用同一个原zval,而其他指向原zval的变量将会指向一个新复制的zval,且refcount会被重新计算,例如:$a=1;$b=$a;$c=$a;$d=&$a;,此时ad使用原zval,bc使用新复制出来的zval
3.当is_ref=1,且refcount>1时,如果将zval复制给某个非引用变量,该非引用变量会使用一个新复制的zval,元zval的refcount不变,服务器空间,例如:$a=1;$b=&$a;$c=$a,那么ab使用原zval,而c使用新复制的zval
type表示该zval的值类型,宏定义如下
复制代码 代码如下:
#define IS_NULL
0
#define IS_LONG
1
#define IS_DOUBLE 2
#define IS_BOOL
3
#define IS_ARRAY 4
#define IS_OBJECT 5
#define IS_STRING 6
#define IS_RESOURCE 7
#define IS_CONSTANT 8
#define IS_CONSTANT_ARRAY 9
复制代码 代码如下:
typedef union _zvalue_value {
long lval;
/* long value */
double dval;
/* double value */
struct {
char *val;
int len;
} str;
HashTable *ht;
/* hash table value */
zend_object_value obj;
} zvalue_value;
复制代码 代码如下:
.-----------
$a = 1;
$b = $a;
$c = $a;
.-----------
$d = &$a;
.-----------
$a = 2;
.-----------
$b = null;