>백엔드 개발 >PHP 문제 >PHP에서 gc는 무엇을 의미합니까?

PHP에서 gc는 무엇을 의미합니까?

青灯夜游
青灯夜游원래의
2022-03-10 15:26:112402검색

PHP에서 gc의 전체 이름은 중국어로 "가비지 컬렉션"을 의미하는 "가비지 컬렉션"입니다. 이는 프로그램에 더 이상 필요하지 않은 할당된 메모리 블록을 자동으로 해제하는 동적 메모리 관리 메커니즘입니다. GC 메커니즘을 사용하면 프로그래머는 프로그램 메모리 할당에 대해 너무 많이 걱정하지 않아도 되므로 비즈니스 로직에 더 많은 에너지를 쏟을 수 있습니다.

PHP에서 gc는 무엇을 의미합니까?

이 튜토리얼의 운영 환경: Windows 7 시스템, PHP 버전 7.1, DELL G3 컴퓨터

PHP에서 gc의 전체 이름은 "Garbage Collection"이며 중국어로 "가비지 컬렉션"을 의미합니다. 일종의 동적 메모리 관리 메커니즘입니다.

가비지 수집 메커니즘(GC)은 프로그램에 더 이상 필요하지 않은 할당된 메모리 블록을 자동으로 해제합니다. 자동으로 메모리를 회수하는 프로세스를 가비지 수집이라고 합니다.

가비지 수집 메커니즘(GC)을 사용하면 프로그래머는 프로그램 메모리 할당에 대해 너무 많이 걱정하지 않아도 되므로 비즈니스 로직에 더 많은 에너지를 쏟을 수 있습니다.

오늘날 인기 있는 다양한 언어 중에서 가비지 수집 메커니즘은 차세대 언어의 공통된 특징입니다.

가비지 생성

문자열, 배열, 객체 등과 같은 PHP7의 복잡한 유형에는 헤더에 gc가 있습니다. 이 gc의 기능은 가비지 수집을 지원하는 것입니다. 변수를 할당하거나 전송할 때 값의 참조 개수가 증가합니다. 변수가 unset, return 등에 의해 해제될 때 뺄셈 후 참조 개수가 0이 되는 경우 해당 참조 번호를 뺍니다. 이는 변수의 기본적인 재활용 과정입니다.

그러나 이 메커니즘으로 해결할 수 없는 한 가지 문제가 있는데, 바로 순환 참조 문제입니다.

순환 참조란 무엇인가요? 간단히 말해서, 변수 내부에 저장된 값은 변수 자체를 참조합니다. 이 비교는 배열 및 객체 유형의 변수에서 자주 발생합니다.

먼저 참조, 즉 zend_reference 유형에 대해 이야기하겠습니다. 이것은 PHP7의 새로운 변수 유형입니다. 변수에 "&" 연산이 사용되면 실제로 이 구조가 생성됩니다. 해당 값에.

예:

// 当进行如下赋值操作时
$a = 'hello'; // $a -> zend_string
$b = $a; // $b,$a -> zend_string
$c = &$b; // $c,$b -> zval(type = IS_REFERENCE, refcount = 2) -> zend_string

결국 다음과 같이 됩니다:

PHP에서 gc는 무엇을 의미합니까?

즉, $b와 $c의 zval은 중간 구조 zend_reference를 통해 최종 zend_string을 가리킵니다.

순환 참조 문제로 돌아가서 배열 순환 참조의 예는 다음과 같습니다.

$a = [1];
$a[] = &$a;
unset($a);

& 연산을 사용한 후 변수 a는 참조 유형이 되고 참조 카운트 refcount는 2가 되며 자체 변수에 할당됩니다. 요소, 즉 변수 a는 자체 참조가 됩니다.

자세한 내용은 다음과 같습니다.

PHP에서 gc는 무엇을 의미합니까?

Unset 후에는 아래 그림과 같습니다.

PHP에서 gc는 무엇을 의미합니까?

즉, $a가 위치한 zval 타입은 IS_UNDEF가 되고, 참조 횟수는 $a가 됩니다. zend_reference 구조체는 1만큼 감소하지만 여전히 0보다 큽니다. 이때 구조체의 이 부분을 처리하지 않으면 메모리 누수가 발생할 수 있습니다. 여기서 이 부분을 버퍼로 수집한 다음 재활용하려면 가비지 수집기가 필요합니다.

재활용 프로세스

변수가 줄어들 때 참조 횟수가 0보다 큰 경우, PHP는 이 변수에 대해 즉시 가비지 식별 및 재활용을 수행하지 않고 버퍼가 가득 찰 때까지( 10000) 버퍼에 넣습니다. 그런 다음 버퍼에 추가되는 것은 zend_value 변수의 gc입니다. 현재 가비지는 배열과 객체의 두 가지 유형에만 나타납니다. 위에서는 배열의 경우입니다. 멤버 속성 참조. 개체 자체로 인해 다른 유형에서는 해당 변수의 멤버가 변수 자체를 참조하지 않으므로 가비지 수집에서는 이 두 가지 유형의 변수만 처리합니다.

gc zend_refcounted_h의 구조는 다음과 같습니다.

typedef struct _zend_refcounted_h {
    uint32_t         refcount; // 记录 zend_value 的引用数
    union {
        struct {
            zend_uchar    type,  // zend_value的类型, 与zval.u1.type一致
            zend_uchar    flags, 
            uint16_t      gc_info // GC信息,记录在 gc 池中的位置和颜色,垃圾回收的过程会用到
        } v;
        uint32_t type_info;
    } u;
} zend_refcounted_h;

변수는 버퍼에 한 번만 추가할 수 있습니다. 반복 추가를 방지하기 위해 변수가 추가된 후 zend_refcounted_h.gc_info는 보라색으로 표시되는 GC_PURPLE로 설정됩니다. , 앞으로 반복해서 삽입되지 않습니다.

가비지 버퍼는 이중 연결 목록입니다. 버퍼가 가득 차면 가비지 검사 프로세스가 시작됩니다. 즉, 버퍼를 순회하고 현재 변수의 모든 멤버를 순회한 다음 해당 멤버의 참조 횟수를 1만큼 줄입니다. member에는 하위 멤버도 포함) 재귀 순회, 즉 깊이 우선 순회를 수행하고 마지막으로 현재 변수의 참조를 확인하여 0으로 감소하면 가비지입니다. 이 알고리즘의 핵심 원리는 멤버가 자신을 참조하여 가비지가 발생하고 모든 멤버에 대한 참조를 줄이는 것입니다. 최종 변수 자체의 참조 횟수가 0이 되면 모든 참조가 자체 변수에서 온다는 의미입니다. 더 이상 사용하지 않으면 쓰레기이므로 재활용해야 합니다. 그렇지 않으면 가비지가 아니므로 버퍼에서 제거해야 함을 의미합니다. 구체적인 과정은 다음과 같습니다:

(1) 버퍼 연결 목록의 루트에서 탐색을 시작하고, 현재 값을 회색으로 표시한 다음(zend_refcounted_h.gc_info를 GC_GREY로 설정), 현재 값의 멤버에 대해 깊이 우선 탐색을 수행하고, 참조 횟수를 줄입니다. 멤버 값을 1로 하고 회색으로 표시합니다.

(2) 버퍼 연결 목록을 반복적으로 탐색하여 현재 값 참조가 0인지 확인합니다. 0이면 실제로 흰색으로 표시됩니다. GC_WHITE) 0이 아닌 경우 멤버의 가능성은 (1)단계에서 멤버의 참조 횟수가 1만큼 감소하므로 외부 참조가 있음을 나타냅니다. , 다시 복원해야 하며 모든 멤버의 깊은 순회가 수행되고 멤버 참조 횟수가 1씩 증가합니다. 동시에 검정색으로 표시됩니다.

(3) 버퍼 연결 목록을 다시 순회하고 비-제거; 루트 연결 목록의 GC_WHITE 노드와 마지막으로 루트 연결 목록은 모두 실제 쓰레기가 되고 마지막으로 이러한 쓰레기를 지웁니다.

추천 학습: "PHP 비디오 튜토리얼"

위 내용은 PHP에서 gc는 무엇을 의미합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.