PHP 是如何做垃圾回收的

包含 php 5 与 php7 的变量实现和垃圾回收的对比

变量的实现

PHP 的变量是弱类型的,可以表示整数、浮点数、字符串等类型。PHP 的变量是使用结构体 zval 表示的

PHP 5.* zval 和 zend_value 结构

struct _zval_struct { // 结构体
zvalue_value value;
zend_uint refcount__gc;
zend_uchar type;
zend_uchar is_ref__gc;
} typedef union _zvalue_value { // 联合体
long lval;
double dval;
struct {
char *val;
int len;
} str; // 字符串
HashTable *ht; // 数组
zend_object_value obj; // 对象
zend_ast *ast;
} zvalue_value;

PHP 7.0 zval 和 zend_value 结构

struct _zval_struct {
union {
zend_long lval; /* long value */
double dval; /* double value */
zend_refcounted *counted;
zend_string *str;
zend_array *arr;
zend_object *obj;
zend_resource *res;
zend_reference *ref;
zend_ast_ref *ast;
zval *zv;
void *ptr;
zend_class_entry *ce;
zend_function *func;
struct {
uint32_t w1;
uint32_t w2;
} ww;
} value;
union {
struct {
ZEND_ENDIAN_LOHI_4(
zend_uchar type, /* active type */
zend_uchar type_flags,
zend_uchar const_flags,
zend_uchar reserved) /* call info for EX(This) */
} v;
uint32_t type_info;
} u1;
union {
uint32_t var_flags;
uint32_t next; /* hash collision chain */
uint32_t cache_slot; /* literal cache slot */
uint32_t lineno; /* line number (for ast nodes) */
uint32_t num_args; /* arguments number for EX(This) */
uint32_t fe_pos; /* foreach position */
uint32_t fe_iter_idx; /* foreach iterator index */
} u2;
};

PHP5 与 PHP7 引用计数的对比

php 5.* 变量赋值等操作引用计数如图所示,在倒数第二步,会形成一个循环引用,并且在 unset 操作之后,会产生垃圾。

PHP 7 的计数放到了具体的 value 中,zval 不存在写时复制(写时分离)。

并且 PHP 7 的有一个专门的 zend_reference 用来表示引用。

有了以上关于 PHP 变量存储的知识,我们可以理解一下 PHP 是如何做垃圾回收的了。

什么是垃圾

首先,我们需要定义什么是垃圾。

  1. refcount 增加的不是
  2. refcount 等于0的不是,这个会被直接清除
  3. refcount 减少,并且不等于0的才可能是垃圾

垃圾收集

  1. php7 要求数据类型是数组和对象,并且 type_flag 是 IS_TYPE_COLLECTABLE
  2. 没有在缓冲区中存在过
  3. 没有被标记过
  4. 标记为紫色,并且放到缓冲区中

回收算法

论文:https://researcher.watson.ibm.com/researcher/files/us-bacon/Bacon01Concurrent.pdf

PHP 5.3 版本以及之后的版本

  1. 将垃圾放到一个 root 池中
  2. 当满 10000 个节点的时候进行垃圾回收
  3. 遍历双向链表中的节点 refcount-1
  4. 遍历双向链表将 refcount=0 的节点删除,到free队列中
  5. 对 refcount!=0 的 refcount+1

PHP 是如何做垃圾回收的的更多相关文章

  1. CLR垃圾回收的设计

    作者: Maoni Stephens (@maoni0) - 2015 附: 关于垃圾回收的信息,可以参照本文末尾资源章节里引用的垃圾回收手册一书. 组件架构 GC包含的两个组件分别是内存分配器和垃圾 ...

  2. JAVA的垃圾回收机制

    1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的 ...

  3. Java基础-gs(垃圾回收)

    Java垃圾回收概况 Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发者,一般不需要专门编写内存回收和垃圾清理代 ...

  4. Java高级之虚拟机垃圾回收机制

    博客出自:http://blog.csdn.net/liuxian13183,转载注明出处! All Rights Reserved ! 区别于C语言手动回收,Java自动执行垃圾回收,但为了执行高效 ...

  5. 转!!Java垃圾回收机制

    1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的 ...

  6. java基础之 垃圾回收机制

    1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的 ...

  7. .Net 垃圾回收和大对象处理

    CLR垃圾回收器根据所占空间大小划分对象.大对象和小对象的处理方式有很大区别.比如内存碎片整理 —— 在内存中移动大对象的成本是昂贵的,让我们研究一下垃圾回收器是如何处理大对象的,大对象对程序性能有哪 ...

  8. 【转载】Java垃圾回收内存清理相关(虚拟机书第三章),GC日志的理解,CPU时间、墙钟时间的介绍

    主要看<深入理解Java虚拟机> 第三张 P84 开始是垃圾收集相关. 1. 1960年诞生于MIT的Lisp是第一门采用垃圾回收的语言. 2. 程序计数器.虚拟机栈.本地方法栈3个区域随 ...

  9. C/C++中几种经典的垃圾回收算法

    1.引用计数算法 引用计数(Reference Counting)算法是每个对象计算指向它的指针的数量,当有一个指针指向自己时计数值加1:当删除一个指向自己的指针时,计数值减1,如果计数值减为0,说明 ...

随机推荐

  1. k 近邻算法解决字体反爬手段|效果非常好

    字体反爬,是一种利用 CSS 特性和浏览器渲染规则实现的反爬虫手段.其高明之处在于,就算借助(Selenium 套件.Puppeteer 和 Splash)等渲染工具也无法拿到真实的文字内容. 这种反 ...

  2. Java修炼——面向对象的三大特征_封装的使用

    封装的作用含义:程序设计追求"高内聚,低耦合" 1.提高代码的安全性 2.提高代码的复用性 3."高内聚":封装细节,便于修改内部代码,提高可 维护性 4.&q ...

  3. servlet登录练习,并且记录访问次数

    Userservlet登录数据处理,包括访问页面次数处理: package com.szxy.test; import java.io.IOException; import javax.servle ...

  4. Koa - 使用koa-multer上传文件(上传限制、错误处理)

    前言 上传文件在开发中是很常见的操作,今天我选择使用koa-multer中间件来实现这一功能,除了上传文件外,我还会对文件上传进行限制,以及发生上传错误时的处理. 由于原来的 koa-multer 已 ...

  5. HTTP 错误 500.19 - Internal Server Error 错误代码 0x80070005 由于权限不足而无法读取配置文件

    HTTP 错误 500.19 - Internal Server Error 无法访问请求的页面,因为该页的相关配置数据无效. 模块 IIS Web Core 通知 未知 处理程序 尚未确定 错误代码 ...

  6. 判断浏览器是否启用cookie

    <!DOCTYPE html> <html> <body onload="checkCookies()"> <script> fun ...

  7. 最简单的 Java内存模型 讲解

    前言 在网上看了很多文章,也看了好几本书中关于JMM的介绍,我发现JMM确实是Java中比较难以理解的概念.网上很多文章中关于JMM的介绍要么是照搬了一些书上的内容,要么就干脆介绍的就是错的.本文试着 ...

  8. ACM/ICPC 2018亚洲区预选赛北京赛站网络赛 D 80 Days (线段树查询最小值)

    题目4 : 80 Days 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 80 Days is an interesting game based on Jules Ve ...

  9. springboot 集成jsp

    建立好springboot项目,确定能成功运行 在application.properties文件中添加 server.context-path=/bootserver.port=8080spring ...

  10. 2016/09/27 Hadoop Yarn

    1.1 YARN基本架构     YARN是Hadoop2.0中的资源管理系统,它的基本设计思想是将MRv1中的JobTracker拆分成了两个独立的服务:一个全局的资源管理器ResourceMana ...