이 글은 주로 PHP 소스 코드 33의 기본 사항인 PHP5.3에 새로 추가된 가비지 수집 메커니즘을 소개합니다. 이제 필요한 친구들이 참고할 수 있도록 공유하겠습니다.
PHP5.3의 새로운 가비지 수집 메커니즘은 매우 발전했다고 합니다. 그 고급 기능을 살펴보겠습니다.
공식 문서를 보시려면 Garbage Collection을 클릭해주세요
중국어 버전 주소: http://docs.php.net/manual/zh/features.gc.php
[가비지 수집 메커니즘 삽입 방법]
zend_gc.h 파일은 zend에서 라인 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_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 빼기 1 연산을 수행했다는 의미
검은색은 기본 색상, 일반
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 중국어 홈페이지를 주목해주세요! 관련 권장 사항:
PHP 소스 코드 32에 대한 간략한 토론: PHP 메모리 풀의 emalloc/efree 계층 및 힙 계층
PHP 소스 코드 31에 대한 간략한 토론: PHP 메모리 풀의 힙( heap) 레이어 기본
PHP 소스 코드에 대한 간략한 토론 30: PHP 메모리 풀의 스토리지 레이어
위 내용은 PHP 소스 코드 33에 대한 간략한 논의: PHP5.3에 새로 추가된 가비지 수집 메커니즘(Garbage Collection)의 기본 사항의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!