PHP 板


LINE

看板 PHP  RSS
※ 引述《rickysu (Ricky)》之铭言: : 题外话: 搞了好久终於注册好 PTT 了。 : ====================================== : 前阵子看到某篇文章提到,要回收物件时, : 使用 $obj = null 会马上回收,unset($obj) 则会比较慢。 : 在解答之前,先来玩个小游戏。 : <?php : class test : { : public function __destruct() : { : echo "object of test is dead\n"; : } : } : $test = new test(); : $test = null; : die("program is end\n"); : 执行结果 : object of test is dead : program is end : 很符合结果 $test = null 先执行 GC (destruct) 接着 die output : =================== : <?php : class test : { : protected $me; : public function __contruct() : { : $this-> me = $this; : } : public function __destruct() : { : echo "object of test is dead\n"; : } : } : $test = new test(); : unset($test); : die("program is end\n"); : 执行结果 : program is end : object of test is dead : unset 没有进行 GC,一直到程式结束後,才开始进行 GC。 : 疑 unset 没有进行 GC ??!! : 好玩的事情发生了,难道真的是 unset 是看心情 GC 的?? : 其实上面的范例即使改成 $test = null; 执行结果也是一样的。 : 这边就先卖个关子,明天再来解答为什麽会有这个结果,以及该怎麽避免这样的问题。 PHP 在判断物件是否该被 GC 启用了 reference counting 的机制来作为判断。 简单的说,当某个物件被参照时就把他的 refcount+1 。 例如 $a = new test(); 他是把 test 物件 refcount + 1, $a 只是一个指向 test 物件的指标。 如果这时候又有一个 $b = $a; php 底层则是把 test 物件的 refcount 再度 + 1。 这也就是为什麽 php 从 5.0 之後物件都是 by referenc 的原因。 一方面为了节省记忆体,一方面则是加快物件引用的处理速度。 那 PHP 怎麽判断一个物件该被执行 GC。 当一个变数被赋予新的数值,或是被 unset ,就会把他对应物件的 refcount-1。 当物件的 refcount 归 0 时,进行 GC (先执行 destructor,再将 memory 回收)。 看起来 reference counting 的机制运作得很完美, 但是某天某位仁兄在 PHP 的 bug report 中发了一个 bug。大致的问题是这样。 他发觉当某个情况时 PHP 会迅速的吃光所有的 memory。 (注: PHP 底层处理 array 跟 object 使用的机制是相同的,都是透过 hashtable ) while(true){ $a = array(1,2,3,4); $a[] = &$a; } 照理来说 $a 被重新 assign array 时,原本的 memory 应该要被释放掉才对。 可是实际状况却不是这样。 Why?? 我们来看一下前面提到的第二个例子 $test = new test(); 首先 constructor 中指定了 $this->me = $this; 这时候 test 物件的 refcount => 1 接着 $test = new test(); refcount = 2 然後执行 unset($test); refcount = 1,因为参照的变数被 unset 所以 -1 这时候好玩的事情发生了 refcount 尚未归 0,所以不会被 GC , 但是已经没有任何变数参照到这个物件了。 这个物件就永远变成垃圾而且无法被回收,除非程式结束才会被回收。 那这个问题在 PHP 5.2 以前的版本是无解的,幸好 PHP 大部分的状况都是一次 request 後就结束,程式结束後 memory 还是会被 OS 回收。 但是随着 framework 的盛行, PHP 中物件被环形引用($a->next = $b; $b->next = $a;)的状况越来越多, 因此 PHP 5.3 开始重新设计整个 GC 机制。 如果有仔细看过 PHP 5.3 的 release note ,除了 namespace 之外 最重大的变动就是多了 gc_collect_cycles, gc_enable, gc_disable。 PHP 5.3 中引入了一个新的演算法,专们用来对付这种环形引用所留下来的垃圾。 如果想看看他是怎运作的可以参考这篇 http://www.php.net/manual/en/features.gc.collecting-cycles.php 不过这种演算法每次都得递回整个引用的物件, 造成的代价相当高。(新版本跑得比之前版本慢是不被允许的) 因此PHP 5.3 会将每个可能需要被 GC 的物件先丢到一个 list 中。 这边所谓的 "可能需要被GC" 是指,只要是物件或是array, 当他被 unreference 时就会先丢到这个暂存 list 中。 当 list 满的时候一次进行 GC (印象中没记错list只能容纳1000个待GC的物件)。 如果想要强制进行 GC 只要呼叫 gc_collect_cycles() ,就会马上进行 GC。 希望这篇文章能让大家对 PHP 的 GC 执行时机有些帮助。 --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.130.136.115
1F:推 gpmm:啧啧啧,把旧文拿出来充数可不行唷 XDD 06/04 16:09
2F:→ rickysu:哈...被发现了,看来得生点有趣的东西。 06/04 16:30
3F:推 chaoms:推第二篇的GC观念和使用说明。但小熟zend engine+只看 06/04 18:19
4F:→ chaoms:第一篇的话会有误解 06/04 18:19
5F:→ xxxzzz:有人用$this->me=$this,也会有原PO讲的情形吗?_ 06/04 22:53
6F:→ xxxzzz:我用$test->me=$test,才会有这种情形,我看官网也是写这样 06/04 22:55
7F:→ xxxzzz:不是写在 __contruct 里面? (我的测试环境php5.2.17) 06/04 22:55
8F:→ rickysu:还没在PHP5.2上实验 ,不过基本的精神是环形引用。 06/05 09:07
9F:→ rickysu:如果是在web server上跑,基本上没啥 memory leak的问题。 06/05 09:10







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Gossiping站内搜寻

TOP