php垃圾回收机制-php引用计数基本知识点

前言

是的,平时经常听到大牛说到的gc,就是垃圾回收器,全称Garbage Collection。

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

乍一看确实没毛病啊,然而其中隐藏着变量内存溢出的风险:http://bugs.php.net/bug.php?id=33595 ,无法回收的内存造成了内存泄漏,所以PHP5.3出现了专门负责清理垃圾数据、防止内存泄漏的GC。

php引用计数基本知识点

首先必须要先讲讲这个会引起垃圾回收的关键基数是怎么回事?

关于php的zval结构体,以及refcount与is_ref的知识点,在菜鸟学php扩展 之 详解php扩展的变量(四) 已描述非常清楚。

不准确但却通俗的说: 
refcount:多少个变量是一样的用了相同的值,这个数值就是多少。 
is_ref:bool类型,当refcount大于2的时候,其中一个变量用了地址&的形式进行赋值,好了,它就变成1了。

主要讲讲如何用php来直观的看到这些计数的变化,走一波。 
首先需要在php上装上xdebug的扩展。

1.第一步:查看内部结构

<?php
    $name = "咖啡色的羊驼";
    xdebug_debug_zval('name');

会得到:

name:(refcount=1, is_ref=0),string '咖啡色的羊驼' (length=18)

2.第二步:增加一个计数

<?php
    $name = "咖啡色的羊驼";
    $temp_name = $name;
    xdebug_debug_zval('name');

会得到:

name:(refcount=2, is_ref=0),string '咖啡色的羊驼' (length=18)

看到了吧,refcount+1了。

3.第三步:引用赋值

<?php
    $name = "咖啡色的羊驼";
    $temp_name = &$name;
    xdebug_debug_zval('name');

会得到:

name:(refcount=2, is_ref=1),string '咖啡色的羊驼' (length=18)

是的引用赋值会导致zval通过is_ref来标记是否存在引用的情况。

4.第四步:数组型的变量

<?php
    $name = ['a'=>'咖啡色', 'b'=>'的羊驼'];
    xdebug_debug_zval('name');

会得到:

name:
(refcount=1, is_ref=0),
array (size=2)
  'a' => (refcount=1, is_ref=0),string '咖啡色' (length=9)
  'b' => (refcount=1, is_ref=0),string '的羊驼' (length=9)

还挺好理解的,对于数组来看是一个整体,对于内部kv来看又是分别独立的整体,各自都维护着一套zval的refount和is_ref。

5.第五步:销毁变量

<?php
    $name = "咖啡色的羊驼";
    $temp_name = $name;
    xdebug_debug_zval('name');
    unset($temp_name);
    xdebug_debug_zval('name');

会得到:

name:(refcount=2, is_ref=0),string '咖啡色的羊驼' (length=18)
name:(refcount=1, is_ref=0),string '咖啡色的羊驼' (length=18)

refcount计数减1,说明unset并非一定会释放内存,当有两个变量指向的时候,并非会释放变量占用的内存,只是refcount减1.

 

详情请查阅转载:https://blog.csdn.net/u011957758/article/details/76864400

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值