この記事では、主に PHP ソース コード 33: PHP5.3 で追加されたガベージ コレクション機構 (Garbage Collection) について紹介します。 PHP ソースコードの
33 について説明します。PHP5.3 の新しいガベージ コレクション機構 (Garbage Collection)
PHP5.3 の新しいガベージ コレクション機構について説明します。非常に先進的だと言われているので、その先進的な実装を見てみたいと思いました。
公式ドキュメントについては、「ガベージ コレクション」をクリックしてください。
中国語版アドレス: 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)
zend_alloc.h の ALLOC_ZVAL マクロの定義は、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 のバッファーされたフィールドを 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 はマクロが多いことで有名で、これよりも多くのマクロが入れ子になっているマクロはたくさんあります。分かりません。さらに、ハンドルおよびその他の構造体は、特にオブジェクト変数を対象としています。
バッファはグローバル変数内にあります。他のモジュールのグローバル変数と同様に、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 のメモリ管理でも同様のことが見られます。ビットは、ある種のマーキング方法として機能します。
ここでは、メモリ割り当ての最後の 2 桁が構造全体のカラー マークとして使用されます。このうち、
白はガベージを意味します
紫はバッファに入れられたことを意味します
灰色は refcount から 1 回の操作が実行されたことを意味します
黒はデフォルト色、通常
[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;};
php5.2.9 バージョンなど、php3.0 より前のバージョンでは、これは 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 中国語 Web サイトに注意してください。
関連する推奨事項:
PHP ソース コード 32: PHP メモリ プールの emalloc/efree 層とヒープ層に関する簡単な説明
PHP ソース コードについての簡単な説明 31: PHP メモリ プールのヒープ層の基本
PHP ソース コードについての簡単な説明 30: PHP メモリ プール
以上がPHP ソースコードの簡単な説明 33: PHP5.3 で追加された新しいガベージ コレクション機構 (Garbage Collection) の基本の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。