分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 运营维护

php 变量的分配和销毁

发布时间:2023-09-06 01:45责任编辑:熊小新关键词:暂无标签

1 引用计数

引用计数是指在value中增加一个字段refcount记录指向当前value的数量,变量复制、函数传参时并不直接硬拷贝一份value数据,而是将refcount++,变量销毁时将refcount--,等到refcount减为0时表示已经没有变量引用这个value,将它销毁即可。

存储结构如下:

 1 typedef struct _zend_refcounted_h { 2 ????uint32_t ????????refcount; ???????????/* reference counter 32-bit */ 3 ????union { 4 ????????struct { 5 ????????????ZEND_ENDIAN_LOHI_3( 6 ????????????????zend_uchar ???type, 7 ????????????????zend_uchar ???flags, ???/* used for strings & objects */ 8 ????????????????uint16_t ?????gc_info) ?/* keeps GC root number (or 0) and color */ 9 ????????} v;10 ????????uint32_t type_info;11 ????} u;12 } zend_refcounted_h;

引用计数的信息位于给具体value结构的gc中,例如在字符串变量中:

1 typedef struct _zend_string ????zend_string;2 struct _zend_string {3 ????zend_refcounted_h gc;4 ????zend_ulong ???????h; ???????????????/* hash value */5 ????size_t ???????????len;6 ????char ?????????????val[1];7 };

2 写时复制

引用计数,多个变量可能指向同一个value,然后通过refcount统计引用数,这时候如果其中一个变量试图更改value的内容则会重新拷贝一份value修改,同时断开旧的指向,写时复制的机制在计算机系统中有非常广的应用,它只有在必要的时候(写)才会发生硬拷贝,可以很好的提高效率

不是所有类型都可以copy的,比如对象、资源,实时上只有string、array两种支持,与引用计数相同,也是通过zval.u1.type_flag标识value是否可复制的

3 变量回收

PHP变量的回收主要有两种:主动销毁、自动销毁。主动销毁指的就是 unset。自动销毁就是PHP的自动管理机制,在return时减掉局部变量的refcount,即使没有显式的return,PHP也会自动给加上这个操作,另外一个就是写时复制时会断开原来value的指向,这时候也会检查断开后旧value的refcount。

4 垃圾回收

PHP变量的回收是根据refcount实现的,当unset、return时会将变量的引用计数减掉,如果refcount减到0则直接释放value,这是变量的简单gc过程

但是实际过程中出现gc无法回收导致内存泄漏的bug,先看下一个例子:

1 $a = [1];2 $a[] = &$a;3 unset($a);

可以看到,unset($a)之后由于数组中有子元素指向$a,所以refcount > 0,无法通过简单的gc机制回收,这种变量就是垃圾,垃圾回收器要处理的就是这种情况,目前垃圾只会出现在array、object两种类型中,所以只会针对这两种情况作特殊处理:当销毁一个变量时,如果发现减掉refcount后仍然大于0,且类型是IS_ARRAY、IS_OBJECT则将此value放入gc可能垃圾双向链表中,等这个链表达到一定数量后启动检查程序将所有变量检查一遍,如果确定是垃圾则销毁释放。

php 变量的分配和销毁

原文地址:https://www.cnblogs.com/dearmrli/p/8576078.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved