一、环境
PHP 7.4
二、前言
PHP的变量在底层有一个引用计数(refcount)属性,这个引用计数是为垃圾回收(GC)服务的,当引用计数变为0的时候,就代表这个变量可以被回收。
但也不是所有的数据类型都支持引用计数,例如一些简单类型如整型、浮点型、布尔型、NULL等,它们就不支持(表现为 refcount 的值恒为0)。不支持 refcount 的数据类型,不会被GC回收,它们在请求结束时才会释放。
可以使用xdebug_debug_zval
函数查看变量的refcount(需要安装xdebug
扩展):
// 整型
$a = 1;
xdebug_debug_zval('a'); // a: (refcount=0, is_ref=0)
// 浮点型
$a = 1.1;
xdebug_debug_zval('a'); // a: (refcount=0, is_ref=0)
// 布尔型
$a = true;
xdebug_debug_zval('a'); // a: (refcount=0, is_ref=0)
// 空值
$a = null;
xdebug_debug_zval('a'); // a: (refcount=0, is_ref=0)
类型与引用计数:
名称 | 类型 | 引用计数 | 备注 |
---|---|---|---|
长整型 | Long | 不支持 | |
浮点型 | Double | 不支持 | |
布尔型 | Bool | 不支持 | |
空值 | NULL | 不支持 | |
字符串 | String | 看条件 | 当字符串是内部字符串(Interned String)时,不支持 |
数组 | Array | 支持 |
当数组是不变数组(Immutable Array)时,refcount的初始值是2,而不是1,所以不变数组的 refcount 不会变为0,即不会被GC回收 |
引用 | Reference | 支持 |
|
资源 | Resource | 支持 |
|
对象 | Object | 支持 |
三、字符串类型
字符串类型分为“内部字符串”和“非内部字符串”。内部字符串不支持refcount,非内部字符串支持refcount,并且两者可以互相转换。
内部字符串就是内容不变的的字符串,例如通过字面量赋值的字符串变量就属于内部字符串:
// 例子1
$a = 'helloworld';
xdebug_debug_zval('a'); // a: (interned, is_ref=0)
// 例子2
$a = 'hello' . 'world';
xdebug_debug_zval('a')