摘要:原文回收周期,增加一篇論文在底部。就是說,僅僅在引用計數減少到非零值時,才會產生垃圾周期。如果他們是循環引用周期的一部分,將永不能被清除進而導致內存泄漏。這個函數將返回使用這個算法回收的周期數。引用計數系統中的同步周期回收
原文:回收周期(Collecting Cycles) ,增加一篇論文在底部。
以下過程僅對數組和對象類型起作用。
傳統上,像以前的 php 用到的引用計數內存機制,無法處理循環的引用內存泄漏。然而 5.3.0 PHP 使用文章? 引用計數系統中的同步周期回收(Concurrent Cycle Collection in Reference Counted Systems)中的同步算法,來處理這個內存泄漏問題。
對算法的完全說明有點超出這部分內容的范圍,將只介紹其中基礎部分。首先,我們先要建立一些基本規則,如果一個引用計數增加,它將繼續被使用,當然就不再在垃圾中。如果引用計數減少到零,所在變量容器將被清除(free)。就是說,僅僅在引用計數減少到非零值時,才會產生垃圾周期(garbage cycle)。其次,在一個垃圾周期中,通過檢查引用計數是否減1,并且檢查哪些變量容器的引用次數是零,來發現哪部分是垃圾。
為避免不得不檢查所有引用計數可能減少的垃圾周期,這個算法把所有可能根(possible roots 都是zval變量容器),放在根緩沖區(root buffer)中(用紫色來標記,稱為疑似垃圾),這樣可以同時確保每個可能的垃圾根(possible garbage root)在緩沖區中只出現一次。僅僅在根緩沖區滿了時,才對緩沖區內部所有不同的變量容器執行垃圾回收操作。看上圖的步驟 A。
在步驟 B 中,模擬刪除每個紫色變量。模擬刪除時可能將不是紫色的普通變量引用數減”1″,如果某個普通變量引用計數變成0了,就對這個普通變量再做一次模擬刪除。每個變量只能被模擬刪除一次,模擬刪除后標記為灰(原文說確保不會對同一個變量容器減兩次”1″,不對的吧)。
在步驟 C 中,模擬恢復每個紫色變量。恢復是有條件的,當變量的引用計數大于0時才對其做模擬恢復。同樣每個變量只能恢復一次,恢復后標記為黑,基本就是步驟 B 的逆運算。這樣剩下的一堆沒能恢復的就是該刪除的藍色節點了,在步驟 D 中遍歷出來真的刪除掉。
算法中都是模擬刪除、模擬恢復、真的刪除,都使用簡單的遍歷即可(最典型的深搜遍歷)。復雜度為執行模擬操作的節點數正相關,不只是紫色的那些疑似垃圾變量。
現在,你已經對這個算法有了基本了解,我們回頭來看這個如何與PHP集成。默認的,PHP的垃圾回收機制是打開的,然后有個 php.ini 設置允許你修改它:zend.enable_gc 。
當垃圾回收機制打開時,每當根緩存區存滿時,就會執行上面描述的循環查找算法。根緩存區有固定的大小,可存10,000個可能根,當然你可以通過修改PHP源碼文件Zend/zend_gc.c中的常量GC_ROOT_BUFFER_MAX_ENTRIES,然后重新編譯PHP,來修改這個10,000值。當垃圾回收機制關閉時,循環查找算法永不執行,然而,可能根將一直存在根緩沖區中,不管在配置中垃圾回收機制是否激活。
當垃圾回收機制關閉時,如果根緩沖區存滿了可能根,更多的可能根顯然不會被記錄。那些沒被記錄的可能根,將不會被這個算法來分析處理。如果他們是循環引用周期的一部分,將永不能被清除進而導致內存泄漏。
即使在垃圾回收機制不可用時,可能根也被記錄的原因是,相對于每次找到可能根后檢查垃圾回收機制是否打開而言,記錄可能根的操作更快。不過垃圾回收和分析機制本身要耗不少時間。
除了修改配置zend.enable_gc ,也能通過分別調用gc_enable() 和 gc_disable()函數來打開和關閉垃圾回收機制。調用這些函數,與修改配置項來打開或關閉垃圾回收機制的效果是一樣的。即使在可能根緩沖區還沒滿時,也能強制執行周期回收。你能調用gc_collect_cycles()函數達到這個目的。這個函數將返回使用這個算法回收的周期數。
允許打開和關閉垃圾回收機制并且允許自主的初始化的原因,是由于你的應用程序的某部分可能是高時效性的。在這種情況下,你可能不想使用垃圾回收機制。當然,對你的應用程序的某部分關閉垃圾回收機制,是在冒著可能內存泄漏的風險,因為一些可能根也許存不進有限的根緩沖區。因此,就在你調用gc_disable()函數釋放內存之前,先調用gc_collect_cycles()函數可能比較明智。因為這將清除已存放在根緩沖區中的所有可能根,然后在垃圾回收機制被關閉時,可留下空緩沖區以有更多空間存儲可能根。
引用計數系統中的同步周期回收(ConcurrentCycleCollection)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/30169.html
摘要:所有這些類型,在內部統一用一個叫做的結構表示,在源代碼中這個結構名稱為。的具體定義在源代碼的文件中,下面是相關代碼的摘錄。 【轉】淺談PHP5中垃圾回收算法(Garbage Collection)的演化 前言 PHP是一門托管型語言,在PHP編程中程序員不需要手工處理內存資源的分配與釋放(使用C編寫PHP或Zend擴展除外),這就意味著PHP本身實現了垃圾回收機制(Garbage C...
摘要:總結垃圾回收機制以的引用計數機制為基礎以前只有該機制同時使用根緩沖區機制,當發現有存在循環引用的時,就會把其投入到根緩沖區,當根緩沖區達到配置文件中的指定數量后,就會進行垃圾回收,以此解決循環引用導致的內存泄漏問題開始引入該機制 php垃圾回收機制,對于PHPer來說是一個不陌生但是又不是很熟悉的內容。那么php是怎么實現對不需要的內存進行回收的呢? php變量的內部存儲結構 首先還是...
摘要:的整個生命周期被劃分為以下幾個階段模塊初始化階段請求初始化階段執行腳本階段請求關閉階段模塊關閉階段。 PHP的整個生命周期被劃分為以下幾個階段:模塊初始化階段(module startup)、請求初始化階段(request startup)、執行腳本階段(executescript)、請求關閉階段(request shutdown)、模塊關閉階段(module shutdown)。根據...
摘要:垃圾回收所謂垃圾就是指通過循環引用自己引用自己,目前只在類型中有出現的形式而導致永遠不為。當出現垃圾之后,的引擎有對應的垃圾回收機制。觸發這個機制的時機是每次出現減少時候。 自嘲)。。。。。2333,我覺得這是因為在php語言層面就幫我們解決了內存回收的問題,但這讓我在和java大牛們吹牛逼的時候,聽到什么內存泄露。。。。(納尼,我tmd怎么從來沒遇見過)一臉懵逼。 本人小菜,如果下面...
閱讀 1961·2021-11-23 09:51
閱讀 873·2021-11-19 09:40
閱讀 829·2021-10-27 14:20
閱讀 5004·2021-10-09 09:52
閱讀 3297·2021-10-09 09:44
閱讀 1729·2021-10-08 10:05
閱讀 5053·2021-09-09 11:47
閱讀 3481·2019-08-30 12:47