이 글에서는 PHP 소스 코드 34에 대해 주로 소개합니다. PHP5.3에 새로 추가된 가비지 컬렉션 메커니즘은 이제 특정 참고 가치가 있어 도움이 필요한 모든 사람들과 공유합니다.
PHP 소스코드에 대해 간단히 이야기해보자 34: PHP5.3에 새로 추가된 가비지 컬렉션 메커니즘(Garbage Collection)
이전 글에서는 PHP 소스코드에 대해 이야기해보자. 33: PHP5.3의 새로운 가비지 수집 메커니즘(Garbage Collection) 기본에서는 가비지 수집 메커니즘에 대한 몇 가지 기본 지식을 소개합니다. 오늘 우리는 초기화를 살펴보고 가비지 버퍼와 가비지 수집 프로세스를 추가합니다.
공식 문서를 보려면 Garbage Collection을 클릭하세요
중국어 버전 주소: http://docs.php.net/manual/zh/features.gc.php
【초기화】#🎜 🎜# zend/zend_gc.c의 121번째 줄에는 gc의 초기화를 구현하는 gc_init 함수가 있습니다. 코드는 다음과 같습니다:
ZEND_API void gc_init(TSRMLS_D){ if (GC_G(buf) == NULL && GC_G(gc_enabled)) { GC_G(buf) = (gc_root_buffer*) malloc(sizeof(gc_root_buffer) * GC_ROOT_BUFFER_MAX_ENTRIES); GC_G(last_unused) = &GC_G(buf)[GC_ROOT_BUFFER_MAX_ENTRIES]; gc_reset(TSRMLS_C); }}123번째 줄은 비어 있는지, gc가 비어 있는지 여부를 결정합니다. 둘 다 true이면 124번째 줄로 이동합니다.
124번째 줄은 malloc을 직접 호출하여 10,000gc_root_buffer 메모리를 할당합니다.
Line 125는 전역 변수 last_unused를 gc 버퍼의 끝 위치로 설정합니다.
126행은 전체 가비지 수집 메커니즘을 재설정합니다. 코드는 다음과 같이 zend/zend_gc.c의 88행에서 시작합니다.
ZEND_API void gc_reset(TSRMLS_D){ GC_G(gc_runs) = 0; GC_G(collected) = 0; #if GC_BENCH GC_G(root_buf_length) = 0; GC_G(root_buf_peak) = 0; GC_G(zval_possible_root) = 0; GC_G(zobj_possible_root) = 0; GC_G(zval_buffered) = 0; GC_G(zobj_buffered) = 0; GC_G(zval_remove_from_buffer) = 0; GC_G(zobj_remove_from_buffer) = 0; GC_G(zval_marked_grey) = 0; GC_G(zobj_marked_grey) = 0;#endif GC_G(roots).next = &GC_G(roots); GC_G(roots).prev = &GC_G(roots); if (GC_G(buf)) { GC_G(unused) = NULL; GC_G(first_unused) = GC_G(buf); GC_G(zval_to_free) = NULL; } else { GC_G(unused) = NULL; GC_G(first_unused) = NULL; GC_G(last_unused) = NULL; }}90~91행은 GC 수의 통계를 설정합니다. 실행(gc_runs)되고 gc의 가비지(수집) 수는 0입니다.
106~107행은 이중 연결 리스트의 헤드 노드의 이전 노드와 다음 노드가 자신을 가리키도록 설정합니다.
구현 코드는 zend/zend.c의 93번째 라인에 다음과 같습니다:
STD_ZEND_INI_BOOLEAN("zend.enable_gc","1",ZEND_INI_ALL,OnUpdateGCEnabled, gc_enabled, zend_gc_globals, gc_globals)초기화 호출은 zend/zend.c의 79번째 라인에 있습니다
static ZEND_INI_MH(OnUpdateGCEnabled) /* {{{ */{ OnUpdateBool(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); if (GC_G(gc_enabled)) { gc_init(TSRMLS_C); } return SUCCESS;}#🎜🎜 #[가비지 버퍼 영역에 추가]Track PHP 소스 코드 zend/zend_execute_API.c 424
[_zval_ptr_dtor] -> [GC_ZVAL_CHECK_POSSIBLE_ROOT()] -> gc_zval_possible_root() ]#🎜 🎜#gc_zval_check_possible_root() 함수에서는 배열과 객체에 대해 가비지 수집 작업만 수행됩니다
gc_zval_possible_root 함수의 코드는 다음과 같습니다
ZEND_API void gc_zval_possible_root(zval *zv TSRMLS_DC){ if (UNEXPECTED(GC_G(free_list) != NULL && GC_ZVAL_ADDRESS(zv) != NULL && GC_ZVAL_GET_COLOR(zv) == GC_BLACK) && (GC_ZVAL_ADDRESS(zv) < GC_G(buf) || GC_ZVAL_ADDRESS(zv) >= GC_G(last_unused))) { /* The given zval is a garbage that is going to be deleted by * currently running GC */ return; } if (zv->type == IS_OBJECT) { GC_ZOBJ_CHECK_POSSIBLE_ROOT(zv); return; } GC_BENCH_INC(zval_possible_root); if (GC_ZVAL_GET_COLOR(zv) != GC_PURPLE) { GC_ZVAL_SET_PURPLE(zv); if (!GC_ZVAL_ADDRESS(zv)) { gc_root_buffer *newRoot = GC_G(unused); if (newRoot) { GC_G(unused) = newRoot->prev; } else if (GC_G(first_unused) != GC_G(last_unused)) { newRoot = GC_G(first_unused); GC_G(first_unused)++; } else { if (!GC_G(gc_enabled)) { GC_ZVAL_SET_BLACK(zv); return; } zv->refcount__gc++; gc_collect_cycles(TSRMLS_C); zv->refcount__gc--; newRoot = GC_G(unused); if (!newRoot) { return; } GC_ZVAL_SET_PURPLE(zv); GC_G(unused) = newRoot->prev; } newRoot->next = GC_G(roots).next; newRoot->prev = &GC_G(roots); GC_G(roots).next->prev = newRoot; GC_G(roots).next = newRoot; GC_ZVAL_SET_ADDRESS(zv, newRoot); newRoot->handle = 0; newRoot->u.pz = zv; GC_BENCH_INC(zval_buffered); GC_BENCH_INC(root_buf_length); GC_BENCH_PEAK(root_buf_peak, root_buf_length); } }}#🎜 🎜#Lines 132~140 zval 매듭 확인 포인트 정보가 노드 버퍼에 들어갔는지 여부, 노드 버퍼에 넣었다면 직접 반환하여 성능을 최적화할 수 있음
Lines 142 ~145 객체 노드를 직접 처리하고 더 이상 후속 작업을 수행하지 않습니다.
149행은 노드가 보라색으로 표시되었는지 여부를 결정합니다. 이는 더 이상 노드 버퍼에 추가되지 않습니다. 노드가 버퍼 작업에 추가만 수행하는지 확인하는 것입니다.
150행은 노드의 색상을 보라색으로 표시하여 이 노드가 버퍼에 추가되었으며 다음에 추가할 필요가 없음을 나타냅니다.
알아보기 153~157번째 줄에는 새 노드의 위치입니다. 버퍼가 가득 차면 가비지 수집 작업이 수행됩니다.
176~184번째 줄은 버퍼가 위치한 이중 연결 리스트에 새로운 노드를 추가합니다.
[가비지 수집 프로세스]
gc_zval_possible_root 함수에서 버퍼가 가득 차면 프로그램은 gc_collect_cycles 함수를 호출하여 가비지 수집 작업을 수행합니다. zend/zend_gc.c 파일의 615번째 줄부터 구현 코드는 다음과 같습니다:ZEND_API int gc_collect_cycles(TSRMLS_D){ int count = 0; if (GC_G(roots).next != &GC_G(roots)) { zval_gc_info *p, *q, *orig_free_list, *orig_next_to_free; if (GC_G(gc_active)) { return 0; } GC_G(gc_runs)++; GC_G(zval_to_free) = FREE_LIST_END; GC_G(gc_active) = 1; gc_mark_roots(TSRMLS_C); gc_scan_roots(TSRMLS_C); gc_collect_roots(TSRMLS_C); orig_free_list = GC_G(free_list); orig_next_to_free = GC_G(next_to_free); p = GC_G(free_list) = GC_G(zval_to_free); GC_G(zval_to_free) = NULL; GC_G(gc_active) = 0; /* First call destructors */ while (p != FREE_LIST_END) { if (Z_TYPE(p->z) == IS_OBJECT) { if (EG(objects_store).object_buckets && EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].valid && EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.refcount <= 0 && EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.dtor && !EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].destructor_called) { EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].destructor_called = 1; EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.refcount++; EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.dtor(EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.object, Z_OBJ_HANDLE(p->z) TSRMLS_CC); EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.refcount--; } } count++; p = p->u.next; } /* Destroy zvals */ p = GC_G(free_list); while (p != FREE_LIST_END) { GC_G(next_to_free) = p->u.next; if (Z_TYPE(p->z) == IS_OBJECT) { if (EG(objects_store).object_buckets && EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].valid && EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.refcount <= 0) { EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.refcount = 1; Z_TYPE(p->z) = IS_NULL; zend_objects_store_del_ref_by_handle_ex(Z_OBJ_HANDLE(p->z), Z_OBJ_HT(p->z) TSRMLS_CC); } } else if (Z_TYPE(p->z) == IS_ARRAY) { Z_TYPE(p->z) = IS_NULL; zend_hash_destroy(Z_ARRVAL(p->z)); FREE_HASHTABLE(Z_ARRVAL(p->z)); } else { zval_dtor(&p->z); Z_TYPE(p->z) = IS_NULL; } p = GC_G(next_to_free); } /* Free zvals */ p = GC_G(free_list); while (p != FREE_LIST_END) { q = p->u.next; FREE_ZVAL_EX(&p->z); p = q; } GC_G(collected) += count; GC_G(free_list) = orig_free_list; GC_G(next_to_free) = orig_next_to_free; } return count;}619번째 줄은 버퍼가 비어 있는지 여부를 결정합니다. 비어 있으면 가비지 수집 작업이 수행되지 않습니다. 수행됨
622행은 가비지 수집 작업이 진행 중인지 확인합니다. 진행 중이면 직접 반환합니다.
625~627행 가비지 수집 작업 수에 1을 더하고 사용 가능 목록을 초기화한 후 설정합니다. gc_active를 1로 설정하여 가비지 반환이 진행 중임을 나타냅니다.
Line 629 이것이 알고리즘의 C단계입니다. 알고리즘은 다시 한번 각 루트 노드에 대해 깊이 우선 검색을 사용하고 참조 개수가 0이면 변수 컨테이너가 0보다 큰 경우 작업이 수행됩니다. 이 시점에서 깊이 우선 탐색을 사용하여 참조 카운트를 1씩 감소시키는 작업이 재개된 다음 참조 카운트가 1만큼 증가합니다.
라인 630의 알고리즘의 마지막 단계 D, 알고리즘이 순회합니다. 거기에서 변수 컨테이너 루트(zval 루트)를 제거하는 동시에 이전 단계에서 흰색으로 표시된 변수 컨테이너가 있는지 확인합니다. [gc_collect_cycles() -> gc_collect_roots() -> zval_collect_white() ]에서 흰색으로 표시된 노드가 전역 변수 zval_to_free 목록에 추가됩니다.
라인. 632~633 전역 변수 free_list 및 next_to_free를 해당 임시 변수에 저장하고 마지막에 현재 상태로 복원됩니다.
634~635행은 지워야 할 목록을 초기화하고 zval 목록을 지웁니다. 가비지 수집 작업 상태를 비활성 상태로 설정합니다.
639~655번째 줄은 소멸자를 처음으로 호출하고 지워진 변수의 수를 계산합니다.
657~678번째 줄의 변수 지우기#🎜🎜 # 682~686행 메모리 해제
687~689행은 가비지 번호 통계 처리 및 free_list 및 next_to_free 변수 복원# 🎜🎜#
위 내용은 이 글의 전체 내용입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지를 주목해주세요
관련 추천:
PHP 소스 코드에 대한 간략한 토론 33: PHP5.3의 새로운 가비지 수집 메커니즘(가비지 수집)의 기본
PHP 소스 코드에 대한 간략한 토론 32: PHP의 emalloc/efree 레이어 및 힙 메모리 풀) 레이어
PHP 소스 코드 29에 대한 간략한 토론: 인터페이스 상속에 대하여
위 내용은 PHP 소스 코드 34에 대한 간략한 논의: PHP5.3에 새로 추가된 가비지 수집 메커니즘(Garbage Collection)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

PHP는 현대적인 프로그래밍, 특히 웹 개발 분야에서 강력하고 널리 사용되는 도구로 남아 있습니다. 1) PHP는 사용하기 쉽고 데이터베이스와 완벽하게 통합되며 많은 개발자에게 가장 먼저 선택됩니다. 2) 동적 컨텐츠 생성 및 객체 지향 프로그래밍을 지원하여 웹 사이트를 신속하게 작성하고 유지 관리하는 데 적합합니다. 3) 데이터베이스 쿼리를 캐싱하고 최적화함으로써 PHP의 성능을 향상시킬 수 있으며, 광범위한 커뮤니티와 풍부한 생태계는 오늘날의 기술 스택에 여전히 중요합니다.

PHP에서는 약한 참조가 약한 회의 클래스를 통해 구현되며 쓰레기 수집가가 물체를 되 찾는 것을 방해하지 않습니다. 약한 참조는 캐싱 시스템 및 이벤트 리스너와 같은 시나리오에 적합합니다. 물체의 생존을 보장 할 수 없으며 쓰레기 수집이 지연 될 수 있음에 주목해야합니다.

\ _ \ _ 호출 메소드를 사용하면 객체를 함수처럼 호출 할 수 있습니다. 1. 객체를 호출 할 수 있도록 메소드를 호출하는 \ _ \ _ 정의하십시오. 2. $ obj (...) 구문을 사용할 때 PHP는 \ _ \ _ invoke 메소드를 실행합니다. 3. 로깅 및 계산기, 코드 유연성 및 가독성 향상과 같은 시나리오에 적합합니다.

섬유는 PHP8.1에 도입되어 동시 처리 기능을 향상시켰다. 1) 섬유는 코 루틴과 유사한 가벼운 동시성 모델입니다. 2) 개발자는 작업의 실행 흐름을 수동으로 제어 할 수 있으며 I/O 집약적 작업을 처리하는 데 적합합니다. 3) 섬유를 사용하면보다 효율적이고 반응이 좋은 코드를 작성할 수 있습니다.

PHP 커뮤니티는 개발자 성장을 돕기 위해 풍부한 자원과 지원을 제공합니다. 1) 자료에는 공식 문서, 튜토리얼, 블로그 및 Laravel 및 Symfony와 같은 오픈 소스 프로젝트가 포함됩니다. 2) 지원은 StackoverFlow, Reddit 및 Slack 채널을 통해 얻을 수 있습니다. 3) RFC에 따라 개발 동향을 배울 수 있습니다. 4) 적극적인 참여, 코드에 대한 기여 및 학습 공유를 통해 커뮤니티에 통합 될 수 있습니다.

PHP와 Python은 각각 고유 한 장점이 있으며 선택은 프로젝트 요구 사항을 기반으로해야합니다. 1.PHP는 간단한 구문과 높은 실행 효율로 웹 개발에 적합합니다. 2. Python은 간결한 구문 및 풍부한 라이브러리를 갖춘 데이터 과학 및 기계 학습에 적합합니다.

PHP는 죽지 않고 끊임없이 적응하고 진화합니다. 1) PHP는 1994 년부터 새로운 기술 트렌드에 적응하기 위해 여러 버전 반복을 겪었습니다. 2) 현재 전자 상거래, 컨텐츠 관리 시스템 및 기타 분야에서 널리 사용됩니다. 3) PHP8은 성능과 현대화를 개선하기 위해 JIT 컴파일러 및 기타 기능을 소개합니다. 4) Opcache를 사용하고 PSR-12 표준을 따라 성능 및 코드 품질을 최적화하십시오.

PHP의 미래는 새로운 기술 트렌드에 적응하고 혁신적인 기능을 도입함으로써 달성 될 것입니다. 1) 클라우드 컴퓨팅, 컨테이너화 및 마이크로 서비스 아키텍처에 적응, Docker 및 Kubernetes 지원; 2) 성능 및 데이터 처리 효율을 향상시키기 위해 JIT 컴파일러 및 열거 유형을 도입합니다. 3) 지속적으로 성능을 최적화하고 모범 사례를 홍보합니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SecList
SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

DVWA
DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

드림위버 CS6
시각적 웹 개발 도구

WebStorm Mac 버전
유용한 JavaScript 개발 도구
