PHP 是如何做垃圾回收的
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 是如何做垃圾回收的了。
什么是垃圾
首先,我们需要定义什么是垃圾。
- refcount 增加的不是
- refcount 等于0的不是,这个会被直接清除
- refcount 减少,并且不等于0的才可能是垃圾
垃圾收集
- php7 要求数据类型是数组和对象,并且 type_flag 是 IS_TYPE_COLLECTABLE
- 没有在缓冲区中存在过
- 没有被标记过
- 标记为紫色,并且放到缓冲区中
回收算法
论文:https://researcher.watson.ibm.com/researcher/files/us-bacon/Bacon01Concurrent.pdf
PHP 5.3 版本以及之后的版本
- 将垃圾放到一个 root 池中
- 当满 10000 个节点的时候进行垃圾回收
- 遍历双向链表中的节点 refcount-1
- 遍历双向链表将 refcount=0 的节点删除,到free队列中
- 对 refcount!=0 的 refcount+1
PHP 是如何做垃圾回收的的更多相关文章
- CLR垃圾回收的设计
作者: Maoni Stephens (@maoni0) - 2015 附: 关于垃圾回收的信息,可以参照本文末尾资源章节里引用的垃圾回收手册一书. 组件架构 GC包含的两个组件分别是内存分配器和垃圾 ...
- JAVA的垃圾回收机制
1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的 ...
- Java基础-gs(垃圾回收)
Java垃圾回收概况 Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发者,一般不需要专门编写内存回收和垃圾清理代 ...
- Java高级之虚拟机垃圾回收机制
博客出自:http://blog.csdn.net/liuxian13183,转载注明出处! All Rights Reserved ! 区别于C语言手动回收,Java自动执行垃圾回收,但为了执行高效 ...
- 转!!Java垃圾回收机制
1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的 ...
- java基础之 垃圾回收机制
1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的 ...
- .Net 垃圾回收和大对象处理
CLR垃圾回收器根据所占空间大小划分对象.大对象和小对象的处理方式有很大区别.比如内存碎片整理 —— 在内存中移动大对象的成本是昂贵的,让我们研究一下垃圾回收器是如何处理大对象的,大对象对程序性能有哪 ...
- 【转载】Java垃圾回收内存清理相关(虚拟机书第三章),GC日志的理解,CPU时间、墙钟时间的介绍
主要看<深入理解Java虚拟机> 第三张 P84 开始是垃圾收集相关. 1. 1960年诞生于MIT的Lisp是第一门采用垃圾回收的语言. 2. 程序计数器.虚拟机栈.本地方法栈3个区域随 ...
- C/C++中几种经典的垃圾回收算法
1.引用计数算法 引用计数(Reference Counting)算法是每个对象计算指向它的指针的数量,当有一个指针指向自己时计数值加1:当删除一个指向自己的指针时,计数值减1,如果计数值减为0,说明 ...
随机推荐
- Python爬虫帮你打包下载所有抖音好听的背景音乐,还不快收藏一起听歌【华为云技术分享】
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...
- qs库使用指南
qs是一个流行的查询参数序列化和解析库.可以将一个普通的object序列化成一个查询字符串,或者反过来将一个查询字符串解析成一个object,而且支持复杂的嵌套.它上手很容易: Qs.parse('x ...
- luogu P2783 有机化学之神偶尔会做作弊 |Tarjan+LCA
题目背景 XS中学化学竞赛组教练是一个酷爱炉石的人. 有一天他一边搓炉石一边监考,而你作为一个信息竞赛的大神也来凑热闹. 然而你的化竞基友却向你求助了. "第1354题怎么做"&l ...
- Java并发编程系列-(3) 原子操作与CAS
3. 原子操作与CAS 3.1 原子操作 所谓原子操作是指不会被线程调度机制打断的操作:这种操作一旦开始,就一直运行到结束,中间不会有任何context switch,也就是切换到另一个线程. 为了实 ...
- Eclipse添加spring-tool-suite插件
Eclipse添加spring-tool-suite插件 步骤 1.help --> Eclipse Marketplace,在search框中搜索spring-tool-suite,点击右下角 ...
- Robotframework常见问题收集
一.Robotframework1.7.3控制台乱码处理 1.找到文件C:\Python37\Lib\site-packages\robotide\contrib\testrunner\testrun ...
- WPF之图片处理系列
WPF 中的一些图片处理方法 一,视觉处理(控件展示) 1,显示图片 Image控件展示 Xaml代码: <Image source="/Resources/Images/1.png& ...
- Spring Cloud第十篇 | 分布式配置中心Config
本文是Spring Cloud专栏的第十篇文章,了解前九篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring Clo ...
- Python的小整数池
此处经常会作为面试题!!! 小整数池目的:节省内存,提高执行效率 需要注意的是:Python实现int的时候有个小整数池.为了避免因创建相同的值而重复申请内存空间所带来的效率问题, Python解释器 ...
- Java开发图片浏览器--记录
效果 设计思路 需求分析 图片浏览,上/下一张,放大缩小等基本功能.可以继续拓展的功能:缩略图.旋转,画笔修改等.此外,缩放实现较为简单,所以会出现失真.设计此类软件功能可参考ACDSee或irfan ...