這篇文章主要介紹了關於淺談PHP原始碼三十三:PHP5.3新增加的垃圾回收機制(Garbage Collection)基礎,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下
淺談PHP源碼三十三:PHP5.3新增加的垃圾回收機制(Garbage Collection)基礎
PHP5.3中新增加了垃圾回收機制,據說很先進,據說引誘了我去看看其先進的實現。
官方說明文件請猛擊Garbage Collection
中文版位址:http://docs.php.net/manual/zh/features.gc.php
【垃圾回收機制的嵌入方式】
zend_gc.h檔案在zend.h的749行被引用:#include “zend_gc.h”
從而替換覆蓋了在237行引用的zend_alloc.h檔案中的ALLOC_ZVAL等宏
zend/zend_gc. h檔案的202行開始
/* The following macroses override macroses from zend_alloc.h */#undef ALLOC_ZVAL#define ALLOC_ZVAL(z) \ do {\ (z) = (zval*)emalloc(sizeof(zval_gc_info));\ GC_ZVAL_INIT(z);\ } while (0)
ALLOC_ZVAL宏在zend_alloc.h中的定義是分配一個zval結構的記憶體空間。新的ALLOC_ZVAL宏分配了一個zval_gc_info結構的巨集。 zval_gc_info的結構如下:
zend/zend_gc.h檔案的91行開始:
typedef struct _zval_gc_info { zval z; union { gc_root_buffer *buffered; struct _zval_gc_info *next; } u;} zval_gc_info;
zval_gc_info的第一個成員為zval結構,這就確保其和以zval變數分配的記憶體的開始對齊,從而在zval_gc_info類型指標的強制轉換時,其可以作為zval使用。關於gc_root_buffer等將在後面的結構和實作時介紹,它定義的PHP垃圾回收機制的快取結構。 GC_ZVAL_INIT用來初始化替代了zval的zval_gc_info,它會把zval_gc_info中的成員u的buffered欄位設為NULL,此欄位僅在將其放入垃圾回收緩衝區時才會有值,否則會一直是NULL。
由於PHP中所有的變數都是以zval變數的形式存在,這裡以zval_gc_info取代zval,從而成功實現垃圾收集機制在原有系統中的整合。
這個有點物件導向中多態的感覺。
【垃圾回收機制的儲存方式】
結點結構:
typedef struct _gc_root_buffer { struct _gc_root_buffer *prev;/* double-linked list */ struct _gc_root_buffer *next; zend_object_handle handle;/* must be 0 for zval */ union { zval *pz; zend_object_handlers *handlers; } u;} gc_root_buffer;
很明顯(見註釋,雖然PHP中的註釋很少,但是有些純粹是糾結的註釋) ,這是一個雙向鍊錶。
在聯合體中的pz變數很明顯就是先前定義的多態的zval_gc_info結構,於是其在鍊錶中的目前結點指標可以透過((zval_gc_info*)(pz))->u .buffered獲取,不過在看其源碼中有多處使用到這個調用方式,為何不另起一個宏呢?難道是怕宏太多,不是啊,PHP就是以宏多著稱,比這個宏嵌套多的宏海了去了。不懂。另外handle等結構是特別針對物件變數的。
緩衝區是話在全域變數中的,和其它模組的全域變數一樣,gc也有自己的全域變數存取巨集GC_G(v),同樣對於全域變數存取巨集在是否ZTS下有不同的實現。
在zend_gc.h中定義的全域變數如下:
typedef struct _zend_gc_globals { zend_bool gc_enabled;/* 是否开启垃圾收集机制 */ zend_bool gc_active;/* 是否正在进行 */ gc_root_buffer *buf;/* 预分配的缓冲区数组,默认为10000(preallocated arrays of buffers) */ gc_root_buffer roots;/* 列表的根结点(list of possible roots of cycles) */ gc_root_buffer *unused;/* 没有使用过的缓冲区列表(list of unused buffers) */ gc_root_buffer *first_unused;/* 指向第一个没有使用过的缓冲区结点(pointer to first unused buffer) */ gc_root_buffer *last_unused;/* 指向最后一个没有使用过的缓冲区结点,此处为标记结束用(pointer to last unused buffer) */ zval_gc_info *zval_to_free;/* 将要释放的zval变量的临时列表(temporaryt list of zvals to free) */ zval_gc_info *free_list;/* 临时变量,需要释放的列表开头 */ zval_gc_info *next_to_free;/* 临时变量,下一个将要释放的变量位置*/ zend_uint gc_runs;/* gc运行的次数统计 */ zend_uint collected; /* gc中垃圾的个数 */ // 省略...
【垃圾回收機制中的顏色標記】
#define GC_COLOR 0x03 #define GC_BLACK 0x00#define GC_WHITE 0x01#define GC_GREY 0x02#define GC_PURPLE 0x03 #define GC_ADDRESS(v) \ ((gc_root_buffer*)(((zend_uintptr_t)(v)) & ~GC_COLOR))#define GC_SET_ADDRESS(v, a) \ (v) = ((gc_root_buffer*)((((zend_uintptr_t)(v)) & GC_COLOR) | ((zend_uintptr_t)(a))))#define GC_GET_COLOR(v) \ (((zend_uintptr_t)(v)) & GC_COLOR)#define GC_SET_COLOR(v, c) \ (v) = ((gc_root_buffer*)((((zend_uintptr_t)(v)) & ~GC_COLOR) | (c)))#define GC_SET_BLACK(v) \ (v) = ((gc_root_buffer*)(((zend_uintptr_t)(v)) & ~GC_COLOR))#define GC_SET_PURPLE(v) \ (v) = ((gc_root_buffer*)(((zend_uintptr_t)(v)) | GC_PURPLE))
在PHP的記憶體管理中我們也看到類似的以最後位作為某種類型的標記方式。
這裡以記憶體分配的最後兩位作為整個結構的顏色標記。其中
白色表示垃圾
紫色表示已放入緩衝區
灰色表示已經進行了一次refcount的減一操作
黑色是預設顏色,正常
【zval定義的改變】
PHP3.0版本在zend/zend.h檔中,其定義如下:
struct _zval_struct { /* Variable information */ zvalue_value value;/* value */ zend_uint refcount__gc; zend_uchar type;/* active type */ zend_uchar is_ref__gc;};
在php3.0之前的版本,如php5.2.9版本,在zend/zend.h檔中,其定義如下:
struct _zval_struct { /* Variable information */ zvalue_value value;/* value */ zend_uint refcount; zend_uchar type;/* active type */ zend_uchar is_ref;};
以上就是本文的全部內容,希望對大家的學習有所幫助,更多相關內容請關注PHP中文網!
相關推薦:
淺聊PHP原始碼三十二:PHP記憶體池中的emalloc/efree層與堆(heap)層
淺談PHP源碼三十一:PHP記憶體池中的堆(heap)層基礎
以上是淺談PHP原始碼三十三:PHP5.3新增加的垃圾回收機制(Garbage Collection)基礎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

TheSecretTokeEpingAphp-PowerEdwebSiterUnningSmoothlyShyunderHeavyLoadInVolvOLVOLVOLDEVERSALKEYSTRATICES:1)emplactopCodeCachingWithOpcachingWithOpCacheToreCescriptexecution Time,2)使用atabasequercachingCachingCachingWithRedataBasEndataBaseLeSendataBaseLoad,3)

你應該關心DependencyInjection(DI),因為它能讓你的代碼更清晰、更易維護。 1)DI通過解耦類,使其更模塊化,2)提高了測試的便捷性和代碼的靈活性,3)使用DI容器可以管理複雜的依賴關係,但要注意性能影響和循環依賴問題,4)最佳實踐是依賴於抽象接口,實現鬆散耦合。

是的,優化papplicationispossibleandessential.1)empartcachingingcachingusedapcutorediucedsatabaseload.2)優化的atabaseswithexing,高效Quereteries,and ConconnectionPooling.3)EnhanceCodeWithBuilt-unctions,避免使用,避免使用ingglobalalairaiables,並避免使用

theKeyStrategiestosigantificallyBoostPhpaPplicationPerformenCeare:1)UseOpCodeCachingLikeLikeLikeLikeLikeCacheToreDuceExecutiontime,2)優化AtabaseInteractionswithPreparedStateTementStatementStatementAndProperIndexing,3)配置

aphpdepentioncontiveContainerIsatoolThatManagesClassDeptions,增強codemodocultion,可驗證性和Maintainability.itactsasaceCentralHubForeatingingIndections,因此reducingTightCightTightCoupOulplingIndeSingantInting。

選擇DependencyInjection(DI)用於大型應用,ServiceLocator適合小型項目或原型。 1)DI通過構造函數注入依賴,提高代碼的測試性和模塊化。 2)ServiceLocator通過中心註冊獲取服務,方便但可能導致代碼耦合度增加。

phpapplicationscanbeoptimizedForsPeedAndeffificeby:1)啟用cacheInphp.ini,2)使用preparedStatatementSwithPdoforDatabasequesies,3)3)替換loopswitharray_filtaray_filteraray_maparray_mapfordataprocrocessing,4)conformentnginxasaseproxy,5)

phpemailvalidation invoLvesthreesteps:1)格式化進行regulareXpressecthemailFormat; 2)dnsvalidationtoshethedomainhasavalidmxrecord; 3)


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

WebStorm Mac版
好用的JavaScript開發工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

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

Atom編輯器mac版下載
最受歡迎的的開源編輯器

Dreamweaver CS6
視覺化網頁開發工具