通过实例详细讲解PHP垃圾回收机制-php教程

资源魔 20 0
PHP渣滓收受接管机制

1. PHP能够主动进行内存治理,肃清没有需求的工具,次要应用了援用计数

2. 正在zval构造体中界说了ref_count以及is_ref , ref_count是援用计数 ,标识此zval被几何个变量援用 , 为0时会被销毁。is_ref标识能否应用的 &取地点符强迫援用

3. 为理解决轮回援用内存泄漏成绩 , 应用同步周期收受接管算法。

比方当数组或工具轮回的援用本身 , unset掉数组的时分 , 当refcount-1后还年夜于0的 , 就会被当成疑似渣滓 , 会进行遍历 ,而且模仿的删除了一次refcount-1假如是0就删除了 ,假如没有是0就规复顽固渣滓的孕育发生进程:

<?php
    $a = "new string";
?>
a: (refcount_gc=1, is_ref_gc=0)='new string'

当把$a赋值给另一个变量的时分,$a对应的zval的refcount_gc会加1

<?php
    $a = "new string";
    $b = $a;
?>

此时$a以及$b变量对应的外部存储信息为,$a以及$b同时指向一个字符串"new string" ,它的refcount变为2a,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外部存储信息为:

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都遵照变量的援用以及计数准则,用图来示意:

垃圾回收01.png

上面正在$a中增加一个元素,并将现有的一个元素的值赋给新的元素:

<?php
    $a = array('meaning' => 'life', 'number' => 42);
    $a['name'] = $a['meaning'];
 ?>

那末$a的外部存储为 , "life" 的ref_count变为2 , 42的ref_count是1:

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,值为字符one,另一个索引为1,为$a本身的援用,外部存储以下:

垃圾回收机制02.png

a: (refcount=2, is_ref=1)=array (
0 => (refcount=1, is_ref=0)='one',
1 => (refcount=2, is_ref=1)=…
)

array这个zval的ref_count是2 , 是一个环形援用。这时候对$a进行unset,那末$a会从符号表中删除了,同时$a指向的zval的refcount_gc缩小1.

那末成绩就孕育发生了,$a曾经没有正在符号表中,用户无奈再拜访此变量,然而$a以前指向的zval的refcount_gc变成1而没有是0,因而不克不及被收受接管,从而孕育发生内存泄漏,新的GC要做的工作就是清算此类渣滓。

为理解决轮回援用内存泄漏成绩 , 应用同步周期收受接管算法 , 这类ref_count减1后还年夜于0的会被作为疑似渣滓。

比方当数组或工具轮回的援用本身 , unset掉数组的时分 , 当refcount-1后还年夜于0的 , 会进行遍历 ,而且模仿的删除了一次refcount-1假如是0就删除了 ,假如没有是0就规复。

想理解更多相干内容请拜访PHP中文网:PHP视频教程

以上就是经过实例具体解说PHP渣滓收受接管机制的具体内容,更多请存眷资源魔其它相干文章!

标签: php开发教程 php开发资料 php开发自学 垃圾回收机制

抱歉,评论功能暂时关闭!