PHP的垃圾回收机制代码实例讲解 |
PHP可以自动进行内存管理,清除不需要的对象,主要使用了引用计数 在 为了解决循环引用内存泄露问题 , 使用同步周期回收算法 顽固垃圾的产生过程 <?php $a = "new string"; ?> 代码中, a: (refcount_gc=1, is_ref_gc=0)='new string' 当把 a 赋 值 给 另 外 一 个 变 量 的 时 候 , a赋值给另外一个变量的时候, a赋值给另外一个变量的时候,a对应的zval的 <?php $a = "new string"; $b = $a; ?> 此时 a 和 a和 a和b变量对应的内部存储信息为, a 和 a和 a和b同时指向一个字符串"new string" ,它的refcount变成2 a,b: (refcount_gc=2, is_ref=0)='new string' 当用unset删除$b变量时,“new string” 的refcount_gc会减1变成1 。 <?php $a = "new string"; //a: (refcount_gc=1, is_ref_gc=0)='new string' $b = $a; //a,b: (refcount_gc=2, is_ref=0)='new string' unset($b); //a: (refcount_gc=1, is_ref=0)='new string' ?> 对于普通的变量来说,这一切很正常,但是在复合类型变量(数组和对象)中,会发生比较有意思的事情: <?php $a = array('meaning' => 'life', 'number' => 42); ?>
a: (refcount=1, is_ref=0)=array ( 'meaning' => (refcount=1, is_ref=0)='life', 'number' => (refcount=1, is_ref=0)=42 ) 数组变量本身($a)在引擎内部实际上是一个哈希表,这张表中有两个zval项 meaning和number,所以实际上那一行代码中一共生成了3个zval,这3个zval都遵循变量的引用和计数原则,用图来表示: 下面在 <?php $a = array('meaning' => 'life', 'number' => 42); $a['name'] = $a['meaning']; ?> 那么 a: (refcount=1, is_ref=0)=array ( 'meaning' => (refcount=2, is_ref=0)='life', 'number' => (refcount=1, is_ref=0)=42, 'name' => (refcount=2, is_ref=0)='life' ) 如果将数组的引用赋值给数组中的一个元素,有意思的事情就会发生: <?php $a = array('one'); $a[] = &$a; ?> 这样 a 数 组 就 有 两 个 元 素 , 一 个 索 引 为 0 , 值 为 字 符 o n e , 另 外 一 个 索 引 为 1 , 为 a数组就有两个元素,一个索引为0,值为字符one,另外一个索引为1,为 a数组就有两个元素,一个索引为0,值为字符one,另外一个索引为1,为a自身的引用,内部存储如下: a: (refcount=2, is_ref=1)=array ( 0 => (refcount=1, is_ref=0)='one', 1 => (refcount=2, is_ref=1)=… )
<?php $a = array('one'); $a[] = &$a; unset($a); ?> 那么问题就产生了, a 已 经 不 在 符 号 表 中 , 用 户 无 法 再 访 问 此 变 量 , 但 是 a已经不在符号表中,用户无法再访问此变量,但是 a已经不在符号表中,用户无法再访问此变量,但是a之前指向的zval的 为了解决循环引用内存泄露问题 , 使用同步周期回收算法 , 这种 比如当数组或对象循环的引用自身 , 到此这篇关于PHP的垃圾回收机制代码实例讲解的文章就介绍到这了,更多相关PHP的垃圾回收机制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! |