php中gc是什麼意思
在php中,gc全名為“Garbage Collection”,中文意思為“垃圾回收”,是一種動態記憶體管理機制,它會自動釋放程式不再需要的已分配的記憶體區塊。 GC機制可以讓程式設計師不必過度關心程式記憶體分配,從而將更多的精力投入業務邏輯。
本教學操作環境:windows7系統、PHP7.1版、DELL G3電腦
在php中,gc全名為「 Garbage Collection”,中文意思為“垃圾回收”,是一種動態記憶體管理機制。
垃圾回收機制(GC)會自動釋放程式不再需要的已分配的記憶體區塊。自動回收記憶體的過程叫垃圾收集。
垃圾回收機制(GC)可以讓程式設計師不必過度關心程式記憶體分配,從而將更多的精力投入業務邏輯。
在現在的流行各種語言當中,垃圾回收機制是新一代語言所共有的特徵。
垃圾的產生
PHP7 中複雜類型,像字串、陣列、物件等的資料結構中,頭部都有一個gc, 這個gc 的作用就是用來對垃圾回收的支援。當變數賦值、傳遞時,會增加 value 的引用數, unset、return 等釋放變數時再減掉引用數,減掉後如果發現 refcount 變為 0 則直接釋放 value,這是變數的基本回收過程。
不過有一種問題是這個機制無法解決的,就是循環引用的問題。
什麼是循環引用呢?簡單說就是變數的內部裡存的 value 又引用了變數本身。這種比較經常發生在陣列和物件類型的變數上。
這裡先講一下引用,即zend_reference 這個類型,這個是PHP7 新增的變數類型,當變數使用「&」 操作時,會建立新的中間結構zend_reference,這個結構體會真正的指向對應的value 結構。
舉例:
// 当进行如下赋值操作时 $a = 'hello'; // $a -> zend_string $b = $a; // $b,$a -> zend_string $c = &$b; // $c,$b -> zval(type = IS_REFERENCE, refcount = 2) -> zend_string
最終會變成如下這樣:
#即$b 和$c 的zval 是透過中間結構體zend_reference 再指向最終的zend_string。
回到循環引用的問題,舉個陣列循環引用例子:
$a = [1]; $a[] = &$a; unset($a);
使用& 運算之後,變數a 就變成了引用型別且引用計數refcount 為2,而又賦值給自己裡面的元素,也就是變數a 變成了自己引用自己。
具體如下:
當unset 之後就變成下圖這樣:
即$a 所在的zval 類型已經變成了IS_UNDEF 了,zend_reference 結構體的引用計數減1,但是仍然大於0,這時候,這部分結構體就變成了垃圾,對此不處理的話,就可能會造成記憶體外洩。這裡就需要垃圾收集器將這部分收集到緩衝區,之後再回收處理。
回收過程
如果當變數的refcount 減少後大於0,PHP 並不會立即對這個變數進行垃圾鑑定和回收,而是放入一個緩衝區中,等這個緩衝區滿了以後(10000 個值) 再統一進行處理,加入緩衝區的是變數zend_value 裡的gc,目前垃圾只會出現在數組和物件兩種類型中,數組的情況上面已經介紹了,物件的情況則是成員屬性引用物件本身導致的,其它類型不會出現這種變數中的成員引用變數本身的情況,所以垃圾回收只會處理這兩種類型的變數。
gc 的結構zend_refcounted_h 具體如下:
typedef struct _zend_refcounted_h { uint32_t refcount; // 记录 zend_value 的引用数 union { struct { zend_uchar type, // zend_value的类型, 与zval.u1.type一致 zend_uchar flags, uint16_t gc_info // GC信息,记录在 gc 池中的位置和颜色,垃圾回收的过程会用到 } v; uint32_t type_info; } u; } zend_refcounted_h;
一個變數只能加入一次緩衝區,為了防止重複加入,變數加入後會把zend_refcounted_h.gc_info 置為GC_PURPLE,即標為紫色,後續不會重複插入。
垃圾緩衝區是一個雙向鍊錶,等到快取區滿了以後則啟動垃圾檢查過程:遍歷緩衝區,對當前變數的所有成員進行遍歷,然後把成員的refcount 減1 (如果成員還包含子成員則也進行遞歸遍歷,即深度優先遍歷),最後再檢查當前變數的引用,如果減為了0 則為垃圾。這個演算法的原理核心是:垃圾是由於成員引用自身導致的,那麼就對所有的成員減一遍引用,如果發現最後變數本身的refcount 變為了0 則就表明其引用全部來自自身成員,即其他任何地方都不再使用它,那麼它就是垃圾,需要被回收。反之說明不是垃圾,需要將其從緩衝區移出去。具體的過程如下:
(1) 從緩衝區鍊錶的roots 開始遍歷,把當前value 標為灰色(zend_refcounted_h.gc_info 置為GC_GREY),然後對當前value 的成員進行深度優先遍歷,把成員value 的refcount 減1,並且也標示為灰色;
(2) 重複遍歷緩衝區鍊錶,檢查目前value 引用是否為0,為0 則表示確實是垃圾,把它標為白色(GC_WHITE),如果不為0 則排除了引用全部來自自身成員的可能,表示還有外部的引用,並不是垃圾,這時候因為步驟(1) 對成員進行了refcount 減1 操作,需要再還原回去,對所有成員進行深度遍歷,把成員refcount 加1,同時標為黑色;
(3) 再次遍歷緩衝區鍊錶,將非GC_WHITE 的節點從roots 鍊錶中移出,最終roots 鍊錶中全部為真正的垃圾,最後將這些垃圾清除。
推薦學習:《PHP影片教學》
以上是php中gc是什麼意思的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

PHP 8.4 帶來了多項新功能、安全性改進和效能改進,同時棄用和刪除了大量功能。 本指南介紹如何在 Ubuntu、Debian 或其衍生版本上安裝 PHP 8.4 或升級到 PHP 8.4

Visual Studio Code,也稱為 VS Code,是一個免費的原始碼編輯器 - 或整合開發環境 (IDE) - 可用於所有主要作業系統。 VS Code 擁有大量針對多種程式語言的擴展,可以輕鬆編寫

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

字符串是由字符組成的序列,包括字母、數字和符號。本教程將學習如何使用不同的方法在PHP中計算給定字符串中元音的數量。英語中的元音是a、e、i、o、u,它們可以是大寫或小寫。 什麼是元音? 元音是代表特定語音的字母字符。英語中共有五個元音,包括大寫和小寫: a, e, i, o, u 示例 1 輸入:字符串 = "Tutorialspoint" 輸出:6 解釋 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。總共有 6 個元

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

PHP的魔法方法有哪些? PHP的魔法方法包括:1.\_\_construct,用於初始化對象;2.\_\_destruct,用於清理資源;3.\_\_call,處理不存在的方法調用;4.\_\_get,實現動態屬性訪問;5.\_\_set,實現動態屬性設置。這些方法在特定情況下自動調用,提升代碼的靈活性和效率。
