首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往
您找到你想要的搜索结果了吗?
是的
没有找到

php --垃圾回收机制--引用计数基本知识

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

02

PHP的垃圾回收机制以及大概实现

垃圾回收,简称gc。顾名思义,就是废物重利用的意思。再说这个之前先接触一下内存泄露,大概意思就是申请了一块地儿拉了会儿屎,拉完后不收拾,那么那块儿地就算是糟蹋了,地越用越少,最后一地全是屎。说到底一句,用了记得还。一定程度上说,垃圾回收机制就是用来擦屁股的。 如果用过C语言,那么申请内存的方式是malloc或者是calloc,然后你用完这个内存后,一定不要忘了用free函数去释放掉,这就是传说中手动垃圾回收,一般都是扫地神僧用这种方式。 很多高层次语言中,你这辈子都是接触不到内存管理的,比如世界上最好的语言php,这种语言替你管理了内存,你就安安心心写烂代码即可。写php的,你说你关心内存,我是不怎么相信的,一定是你在装逼。当然了,如果你用的swoole或者wm或者自己发明的常驻内存级php应用,那你将不得不关注内存泄露问题,也就说一定要记得释放无用变量。那么,在用的最普遍地最传统的web开发中,php的自动垃圾回收机制是怎样的呢? 这个问题我们先这么想,就是都知道php是C语言实现的,现在把C语言给你放在这里了,然后你想想如何用C语言实现对一个变量的统计以及释放。你不要想如何实现php,你就想C语言如何实现一个变量,从声明开始到最后没人用了,就把这个变量所占的内存给释放掉。你从这个角度出发,就会舒服一些,这不再是一个技术难题,而是一个傻逼产品经理提的一个傻逼需求。好了,步入正题,PHP进行内存管理的核心算法一共两项:一是引用计数,二是写时拷贝,请理(bei)解(song)。当你声明一个PHP变量的时候,C语言就在底层给你搞了一个叫做zval的struct(结构体);如果你还给这个变量赋值了,比如“hello world”,那么C语言就在底层再给你搞一个叫做zend_value的union(联合体),总体看来就是这样的:

03

掌握PHP垃圾回收机制详解

官网的解答如下 每个php变量存在一个叫”zval”的变量容器中一个zval变量容器,除了包含变量的类型和值 ,还包括两个字节的额外信息 is_ref 和 refcount is_ref 是个bool值,用来标识这个变量是否是属于引用集合(reference set)。通过这个字节,php引擎才能把普通变量和引用变量区分开来 refcount 用以表示指向这个zval变量容器的变量个数 PHP5 中的引用计数在PHP5中,zval 的内存是单独从堆(heap)中分配的(有少数例外情况),PHP 需要知道哪些 zval 是正在使用的,哪些是需要释放的。所以这就需要用到引用计数:zval 中 refcount__gc 的值用于保存 zval 本身被引用的次数,比如 b = 12语句中,12 被两个变量引用,所以它的引用计数就是 2。如果引用计数变成 0,就意味着这个变量已经没有用了,内存也就可以释放了。

03

看看php内存管理机制与垃圾回收机制

定义变量之后,内存增加,清除变量之后,内存恢复(有些可能不会恢复和以前一样),好像定义变量时申请了一次内存,其实不是这样的,php会预先申请一块内存,不会每次定义变量就申请内存。 首先我们要打破一个思维: PHP不像C语言那样, 只有你显示的调用内存分配相关API才会有内存的分配. 也就是说, 在PHP中, 有很多我们看不到的内存分配过程. 比如对于: $a = "laruence"; 隐式的内存分配点就有: 1.1. 为变量名分配内存, 存入符号表 2.2. 为变量值分配内存 所以, 不能只看表象. 第二, 别怀疑,PHP的unset确实会释放内存, 但这个释放不是C编程意义上的释放, 不是交回给OS. 对于PHP来说, 它自身提供了一套和C语言对内存分配相似的内存管理API:

03
领券