刨根问底:PHP 垃圾回收机制(一)

echo 111

GC垃圾回收器(Garbage Collection)


最近在写一个后台同时在线功能接触到删除session,涉及到gc,所以研究一下这个垃圾回收机制到底是怎么回事?


早期版本,准确地说是5.3之前(不包括5.3)的垃圾回收机制,是没有专门的垃圾回收器的。只是简单的判断了一下变量的zval的refcount是否为0,是的话就释放否则不释放直至进程结束。

一、学习下php引用计数基本知识点

了解php的zval结构体,以及refcount与is_ref的知识点

 1,首先给一个变量赋值,然后通过xdebug函数打印zval结构体,分析下里面的数据结构有哪些


      $name = "测试变量";

    xdebug_debug_zval('name');


得到结果
name:
(refcount=1, is_ref=0),string '测试变量' (length=12)
可以看到此时refcount为1
2,再给这个变量一个赋值

   $name = "测试变量";
    $a = $name;
    xdebug_debug_zval('name');

得到结果

name:

(refcount=2, is_ref=0),string '测试变量' (length=12)


此时的refcount已经增加1了,is_ref还是0

3,我们给这个变量引用赋值一次,看看有什么变化


得到结果

name:

(refcount=2, is_ref=1),string '测试变量' (length=12)
可以看到is_ref已经变成1了,所以普通赋值和引用赋值都会使计数器加1,而is_ref是判断是否存在引用,存在则为1,否则为0
4,如果变量为数组呢?


    $name = ['nn'=>'娜娜','hh'=>'呵呵'];
    xdebug_debug_zval('name');
得到结果
name:
(refcount=1, is_ref=0),
array (size=2)
  'nn' => (refcount=1, is_ref=0),string '娜娜' (length=6)
  'hh' => (refcount=1, is_ref=0),string '呵呵' (length=6)
数组和对象等其他多子元素类型可以看为一个整体,该整体只会被计数一次
5,计数器有什么用呢,和垃圾回收机制有什么关系呢?
我们尝试销毁一下变量,看看计数器有什么变化。
    $name = "测试变量";
    $a=$name;
    xdebug_debug_zval('name');
    unset($a);
    xdebug_debug_zval('name');

得到结果
name:
(refcount=2, is_ref=0),string '测试变量' (length=12)
name:
(refcount=1, is_ref=0),string '测试变量' (length=12)
我们发现计数器在unset一个普通赋值变量后减少了1。
总结:unset不一定是会释放内存,当有两个变量指向的时候,不会释放变量占用的内存,只是refcount这个计数器减1。
 




相关推荐

评论 (1)

评论前必须登录!

  注册

  1. 回复

    ssss(2020-12-28 18:06:38)

    22222