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燈, 水草

請輸入看板名稱,例如:BuyTogether站內搜尋

TOP