淺談PHP源碼三十三:PHP5.3新增加的記憶體回收機制(Garbage Collection)基礎

來源:互聯網
上載者:User
這篇文章主要介紹了關於淺談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;};

以上就是本文的全部內容,希望對大家的學習有所協助,更多相關內容請關注topic.alibabacloud.com!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.