前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PHP官方手册研读--php的垃圾回收机制

PHP官方手册研读--php的垃圾回收机制

作者头像
陈大剩博客
发布2023-03-22 17:17:52
4080
发布2023-03-22 17:17:52
举报

概述

php中何为垃圾

在PHP中,没有任何变量指向这个对象时,这个对象就成为垃圾;

垃圾的产生过程

代码语言:javascript
复制
<?php
$a = array('one');
$a[] = &$a;
xdebug_debug_zval('a');
<?php

PHP

Copy

注意,xdebug_debug_zval函数是xdebug扩展的,使用前必须安装xdebug扩展,输出如下

代码语言:javascript
复制
output:
a:(refcount=2, is_ref=1)
array (size=2)
	0 => (refcount=1, is_ref=0)string 'one' (length=3)
	1 => (refcount=2, is_ref=1)  &array<

PHP

Copy

这样$a数组就有两个元素,一个索引为0,值为字符one,另外一个索引为1,为$a自身的引用,内部存储如下:

应用图片
应用图片

那么问题就产生了,$a已经不在符号表中,用户无法再访问此变量,但是$a之前指向的zval的refcount_gc变为1而不是0,因此不能被回收,从而产生内存泄露,GC要做的工作就是清理此类垃圾。

算法(内存泄露)

PHP手册中有简单的介绍GC使用的垃圾清理算法,这个算法名为 Concurrent Cycle Collection in Reference Counted Systems(引用计数系统中的同步周期回收)。

  • 如果一个zval的refcount_gc增加,那么此zval还在使用,不属于垃圾
  • 如果一个zval的refcount减少到0, 那么zval可以被释放掉,不属于垃圾
  • 如果一个zval的refcount减少之后大于0,那么此zval还不能被释放,此zval可能成为一个垃圾

算法介绍:

代码语言:javascript
复制
  A:为避免不得不检查所有引用计数可能减少的垃圾周期,这个算法把所有可能根(possible roots 都是zval变量容器),放在根缓冲区(root buffer)中(用紫色来标记,称为疑似垃圾),这样可以同时确保每个可能的垃圾根(possible garbage root)在缓冲区中只出现一次。仅仅在根缓冲区满了时,才对缓冲区内部所有不同的变量容器执行垃圾回收操作。

  B:模拟删除每个紫色变量。模拟删除时可能将不是紫色的普通变量引用数减”1”,如果某个普通变量引用计数变成0了,就对这个普通变量再做一次模拟删除。每个变量只能被模拟删除一次,模拟删除后标记为灰。

  C:模拟恢复每个紫色变量。恢复是有条件的,当变量的引用计数大于0时才对其做模拟恢复。同样每个变量只能恢复一次,恢复后标记为黑,基本就是步骤 B 的逆运算。这样剩下的一堆没能恢复的就是该删除的蓝色节点了,在步骤 D 中遍历出来真的删除掉。

算法中都是模拟删除、模拟恢复、真的删除,都使用简单的遍历即可(最典型的深搜遍历)。复杂度为执行模拟操作的节点数正相关,不只是紫色的那些疑似垃圾变量。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-05-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • php中何为垃圾
  • 垃圾的产生过程
  • 算法(内存泄露)
  • 算法介绍:
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档