php的垃圾回收机制(gc)

1 篇文章 0 订阅

是的,平时经常听到大牛说到的gc,就是垃圾回收器,全称Garbage Collection。
php引用计数基本知识点
每个php变量存在一个叫“zval”的变量容器中。一个zval变量容器,除了包含变量的类型和值,还包括两个字节的额外信息。第一个是is_ref”,是个bool值,用来标识这个变量是否是属于引用集合(reference set)。通过这个字节,php引擎才能把普通变量和引用变量区分开来,由于php允许用户通过使用&来使用自定义引用,zval变量容器中还有一个内部引用计数机制,来优化内存使用。第二个额外字节是”refcount“,用以表示指向这个zval变量容器的变量(也称符号即symbol)个数。所有的符号(变量名)存在一个符号表中,其中每个符号都有作用域(scope),当一个变量被赋常量值时,就会生成一个zval变量容器。

不准确但却通俗的说:
refcount:多少个变量是一样的用了相同的值,这个数值就是多少。
is_ref:bool类型,当refcount大于2的时候,其中一个变量用了地址&的形式进行赋值,好了,它就变成1了

php的内存管理机制
大致过程:定义变量->内存增加->清除变量->内存恢复
内存中的变化:
当定义变量的时候,内存的分配做了两件事情:1.为变量名分配内存,存入符号表 2.为变量值分配内存。
对于php的核心结构Hashtable来说,由于未知性,定义的时候不可能一次性分配足够多的内存块。所以初始化的时候只会分配一小块,等不够的时候在进行扩容,而Hashtable只扩容不减少,所以就出现了上述的情况:当存入100个变量的时候,符号表不够用了就进行一次扩容,当unset的时候只释放了”为变量值分配内存”,而“为变量名分配内存”是在符号表的,符号表并没有缩小,所以没收回来的内存是被符号表占去了。

php并非简单的向os申请内存,而是会申请一大块内存,把其中一部分分给申请者,这样当再有逻辑来申请内存的时候,就不需要向os申请了,避免了频繁调用。当内存不够的时候才会再次申请。

当释放内存的时候,php并非会把内存还给os,而是把内存轨道自己维护的空闲内存列表,以便重复利用。

php中如何定义垃圾的?
主要是看内存中refcount是否变为0,为零的话就是垃圾。

5.3版本以后php是如何处理垃圾内存的?

判断处理过程

为解决环形引用导致的垃圾,产生了新的GC算法,遵守以下几个基本准则:

1.如果一个zval的refcount增加,那么此zval还在使用,不属于垃圾

2.如果一个zval的refcount减少到0, 那么zval可以被释放掉,不属于垃圾

3.如果一个zval的refcount减少之后大于0,那么此zval还不能被释放,此zval可能成为一个垃圾

unset只是断开一个变量到一块内存区域的连接,同时将该内存区域的引用计数-1;内存是否回收主要还是看refount是否到0了,以及gc算法判断。

总结一下:垃圾回收机制
当定义一个变量时,内存会分配一个zval变量容器,存放变量的值、类型、is_ref_gc,refcount_gc四个参数。当变量被复制,或引用&时,refconut引用计数器就会加1,使用unset时,refcount减去1;所以当refcount = 0或将变量设置为null,或程序执行结束时,释放该变量的内存。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值