详解垃圾回收机制(GC----Garbage Collection)

实现一个变量,从声明开始到最后没人用,就把这个变量所占的内存给释放掉(垃圾回收);

1:引用计数

2:回收周期

3:性能方面考虑的因素

 一、引用计数基本知识

每个php变量存在一个叫“zval”的变量容器中,一个zval变量容器,除了包含变量的类型和值,还包括两个字节的额外信息is_ref和refcount

1:" is_ref ": bool值,用来标识这个变量是否属于引用集合。

                       通过这个字节,php引擎才能把普通变量和引用变量区分开来。php允许使用&符号来自定义引用,zval变量容器中还有一个内部引用计数机制来优化内存使用。

2:" refcount ":用来表示指向这个zval变量容器的变量个数。

代码示例:

<?php
1、$name = "hello world";
echo xdebug_debug_zval('name');

输出:name:(refcount = 1,is_ref = 0) = 'hello world'; 

2、 $name = "hello world";
	$temp_name = $name;
    xdebug_debug_zval('name');

输出:name:(refcount = 2,is_ref = 0) = 'hello world';

3、 $name = "hello world";
	$temp_name = &$name;
    xdebug_debug_zval('name');

输出:name:(refcount = 2,is_ref = 1) = 'hello world'; 

4、$name = 'hello world';
   $temp_name = $name;
   unset($temp_name);       
   xdebug_debug_zval('name');

输出:name:(refcount = 1,is_ref = 0) = 'hello world';

5、$name = ['a'=>'hello','b'=>'world'];
   xdebug_debug_zval('name');

输出:name: ( refcount=1, is_ref=0) = array (
                                           'a' => (refcount=1, is_ref=0)='hello',
                                           'b' => (refcount=1, is_ref=0)='world'
                                   )

注:unset:当有两个变量指向的时候,unset并非会释放变量所占的内存,只是refcount-1;

【unset只是断开一个变量到一块内存区域的链接,并非会释放内存】

二、回收周期 

php如何打开垃圾回收机制?

1、php.ini 中zend.enable_gc = On;

2、gc_enable()和gc_disable()函数来打开和关闭垃圾回收机制;

3、gc_collect_cycles()返回算法回收的周期数, 在节点缓冲区未满的情况下强制执行垃圾分析算法

在这之前,我们应该了解什么叫做垃圾???php中的垃圾是如何定义的?????

           如果一个引用计数增加,他将继续被使用,当然就不在垃圾中了;

           如果引用计数减少到零时,所在变量容器将会被清除;

           其实也就是看refcount是不是等于0了;

言归正传,说回收周期…………

<?php
	$a = ['one']; --- zval_a(将$a对应的zval,命名为zval_a)
	$a[] = &$a; --- step1
	unset($a);  --- step2


step1  输出:a: (refcount=2, is_ref=1)  
        = array (
                  0 => (refcount=2, is_ref=0)='one', 
                  1 => (refcount=2, is_ref=1)=...)

step2  输出:a: no such symbol

算法总的套路:

大致过程:定义变量->内存增加->清除变量->内存恢复

对于一个包含环形引用的数组,对数组中包含的每个元素的zval进行减1操作,之后如果发现数组自身的zval的refcount变成了0,那么可以判断这个数组是一个垃圾。

三、性能方面

1、实现垃圾回收机制的原因是为了通过清理循环引用的变量来节省内存占用;

2、PHP中的垃圾回收机制,仅仅在循环回收算法确实运行时会有时间消耗上的增加。但是在平常的(更小的)脚本中应根本就没有性能影响。

四、php函数 垃圾回收机制的

1、unset:    unset()只是断开一个变量到一块内存区域的链接,同时将该内存区域的refcount-1;  具体的内存是否回收还是要看refcount是否等于0;

2、null:   null()是将数据结构置空,同时将refcount变成0;

3、脚本执行结束,该脚本使用的内存都会被释放,不论是否有引用;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值