php 垃圾回收机制

理解PHP垃圾回收机制(GC)之前,先了解一下变量的存储。

在php 手册中已经讲的很清楚了

基础定义:

https://www.php.net/manual/zh/features.gc.refcounting-basics.php  可以去这里翻翻手册看一下

 

简单的概述一下

每个php变量存在一个叫"zval"的变量容器中。
一个zval变量容器,除了包含变量的类型和值,
还包括两个字节的额外信息。
第一个是"is_ref",是个bool值,用来标识这个变量是否是属于引用集合(reference set)。通过这个字节,php引擎才能把普通变量和引用变量区分开来,由于php允许用户通过使用&来使用自定义引用,zval变量容器中还有一个内部引用计数机制,来优化内存使用。
第二个额外字节是"refcount",用以表示指向这个zval变量容器的变量(也称符号即symbol)个数。所有的符号存在一个符号表中,其中每个符号都有作用域(scope),那些主脚本(比如:通过浏览器请求的的脚本)和每个函数或者方法也都有作用域。

 

 

 

所以在此不再过多的解释php 变量。

 

在5.2及更早版本的PHP中,没有专门的垃圾回收器GC(Garbage Collection),引擎在判断一个变量空间是否能够被释放的时候是依据这个变量的zval的refcount的值,如果refcount为0,那么变量的空间可以被释放,否则就不释放,这是一种非常简单的GC实现,这是引用计数内存机制。

那为什么会需要垃圾回收呢?

因为在php中存在环状引用导致内存泄露,在之前的5.2 是回收不了的

PHP5.3中,采用了专门的算法来解决此事

  1. 如果一个zval的refcount增加,那么此zval还在使用,肯定不是垃圾,不会进入缓冲区。
  2. 如果一个zval的refcount减少到0, 那么zval会被立即释放掉,不属于GC要处理的垃圾对象,不会进入缓冲区。
  3. 如果一个zval的refcount减少之后大于0,那么此zval还不能被释放,此zval可能成为一个垃圾,将其放入缓冲区。PHP5.3中的GC针对的就是这种zval进行的处理。

 

如何实现垃圾回收机制呢?

开启/关闭垃圾回收机制可以通过修改php配置实现,也可以在程序中使用gc_enable() 和 gc_disable()开启和关闭。

 

注意:

PHP中的垃圾回收机制,仅仅在循环回收算法确实运行时会有时间消耗上的增加

 

posted @ 2021-06-14 17:32  方达达  阅读(6)  评论(0编辑  收藏  举报