PHP内存管理之unset
作者 斯人 | 发布于 2012 年 3 月 12 日
PHP PHP内核

今天博客还没有更新,刚才给老妈刻了点CD.舞曲的..确实不好找啊.很多舞曲网站还都收费….

最后不得已用了点办法找到了歌曲的真实连接..

步入正题吧..想了半天..今天还没想好写点什么…

于是网上找了一道笔试题…来研究研究

先看如下代码

$test = 'siren';
$abc = & $test;
unset($test);
echo $abc;

这是什么??如果按照C的内存处理机制..
$abc指向了$test的内存地址.
如果将test的内存删掉, $abc所指向的内存也会消失..那么$abc的值就是null了..
PHP的结果是什么?程序跑一下
结果竟然输出siren…
OH MY god!是不是哪里搞错了…为什么会这样??
这就不得不说说unset了..
严格的说,unset并不是一个函数,而是一个语言结构
主要操作是从当前符号表中删除参数中的符号,比如在全局代码中执行unset($a),那么将会在全局符号表中删
除a这个符号。
全局符号表是一张哈希表,建立这张表的时候会提供一个表中的项的析构函数,当我们从符号表
中删除a的时候,会对符号a指向的项(这里是zval的指针)调用这个析构函数,这个析构函数的主要功能是将a对应的zval的refcount减1,如果refcount变成了0,那么释放这个zvall。
所以当我们调用unset的时候,不一定能释放变量所占的内存空间,只有当这个变量对应的zval没有别的变量指向它的时候,才会释放掉zval,否则只是对refcount进行减1操作。
unset 销毁的是指向对象的变量,而不是这个对象,触发的__destruct() 析构函数是用来回收变量内存空间,是在垃圾对象被回收时执行。
回到上面的代码,
unset($test);这里虽然是unset,但并没有删除掉$test所存放的数据,只是symbol_table中删掉test这个符号.并且执行refcount__gc–.原来的内存还保存着test原来的数据,因为$abc所指向的内存是test所在的内存,所以我们最后输出$abc就等于
输出了test所在内存区的值.

原文出处:http://www.imsiren.com/archives/406