小谈php的垃圾回收机制

上周五这个时候到新东家面试,里面有一题,谈谈php的垃圾回收机制(garbage collect,简称GC),当时脑子想到的笼统的概念是当对象不使用时便被回收了。回来后,便想着要把这题给解决掉,今儿上午正好有空,于是抽时间小小的研究了下。


先讲讲session的GC机制,具体的可以看下php.ini中这段介绍

; Defines the probability that the 'garbage collection' process is started
; on every session initialization. The probability is calculated by using
; gc_probability/gc_divisor. Where session.gc_probability is the numerator
; and gc_divisor is the denominator in the equation. Setting this value to 1
; when the session.gc_divisor value is 100 will give you approximately a 1% chance
; the gc will run on any give request.

大意就是GC是依据session中的gc_probability/gc_divisor的概率来启动的,如果gc_probability为1,gc_divisor为1000,那么只有千分之一的概率启动GC,也就是说在1000次的session会话中,只有一次可以启动GC。其中gc_probability和gc_divisor都可以通过配置php.ini中session.gc_probability和session.gc_divisor的值来改变,也可以在php脚本中使用ini_set(session.gc_probability, 1)及ini_set(session.gc_divisor, 100)来重新设定。


在GC启动后,会扫描所有的session信息,用当前时间减去session最后修改的时间,同session.gc_maxlifetime(一般为1440秒,也就是24分钟)参数进行比较,如果生存时间超过gc_maxlifetime,就将该session删除。


再来谈谈变量的GC机制。php可以自动进行内存管理,清除不再需要的对象。php使用了引用计数(reference counting)这种单纯的GC机制。每个对象都内含一个引用计数器,每个引用(reference)连接到对象,计数器加1。当reference离开生存空间或被设为NULL,计数器减1。当某个对象的引用计数器为零时,php知道你将不再需要使用这个对象,释放其所占的内存空间。


下面举几个简单的示例


eg1.

#refcount=1
$a = 'good';

#refcount=2
$b = &$a;

echo $a; // good

echo $b; // good

这例子可以理解为在内存开辟一个空间,值为字符串good,并且一个名为$a的变量指向这块内存,同时php内部有个符号表,用来记录各块内存引用计数,那么此时会将这块内存的引用计数 加 1。接下来$b = &$a,这是引用传值,也就是$b的变量也指向了这块内存,同时引用计数加1,此时为2。


eg2

#refcount=1
$a = 'good';

#refcount=2
$b = &$a;

$a = 'test';

echo $a; // test

echo $b; // test

因为$a和$b都指向同一块内存,因此当把$b的值改了,那么$a的值也就跟着变了。


eg3

#refcount=1
$a = 'good';

#refcount=2
$b = &$a;

#refcount=1
unset($a);

echo $a; // Notice: Undefined variable: a in E:\www\test\1408\15.php on line 16

echo $b; // good

看到这里,有的朋友应该有点疑惑了,为什么$b还有值的。其实unset这个操作只是把$a指向的那块内存的引用给断开了,并且使那块内存在符号表中引用计数减1,但并没有影响到其他指向这块内存的变量,因此$b的值还是good。只有当一块内存在符号表中的引用计数为 0 时,php引擎才会将这块内存回收。


eg4

#refcount=1
$a = 'good';

#refcount=2
$b = &$a;

#refcount=0
$a = null;

echo $a; // 

echo $b; // 


把$a赋值null,结果是直接把指向那个块内存的引用置为0了并且那块内存也便释放了,也就相当于$a和$b变量的值都为null,因为原来的那块内存已经被释放掉了。


就简单的谈到这,如果想深入的了解,请参照PHP内核探索:新垃圾回收机制说明

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值