>  기사  >  백엔드 개발  >  PHP 가비지 수집 메커니즘 - 재활용 주기

PHP 가비지 수집 메커니즘 - 재활용 주기

伊谢尔伦
伊谢尔伦원래의
2016-11-22 09:59:271161검색

일반적으로 PHP에서 사용되는 참조 계산 메모리 메커니즘은 순환 참조 메모리 누수를 처리할 수 없습니다. 그러나 5.3.0 PHP에서는 이 메모리 누수 문제를 처리하기 위해 » 참조 카운트 시스템의 동시 주기 수집 문서에 있는 동기화 알고리즘을 사용합니다.

알고리즘에 대한 완전한 설명은 이 섹션의 범위를 벗어나므로 기본 사항만 소개합니다. 먼저, 몇 가지 기본 규칙을 설정해야 합니다. 참조 횟수가 증가하면 계속 사용되며 더 이상 가비지에는 포함되지 않습니다. 참조 횟수가 0으로 줄어들면 변수 컨테이너가 지워집니다(무료). 즉, 가비지 사이클은 참조 카운트가 0이 아닌 값으로 감소할 때만 발생합니다. 둘째, 가비지 사이클 동안 참조 횟수가 1만큼 감소하는지 확인하고 참조가 0인 변수 컨테이너를 확인하여 어떤 부분이 가비지인지 알아냅니다.

PHP 가비지 수집 메커니즘 - 재활용 주기

참조 횟수가 줄어들 수 있는 모든 가비지 사이클을 확인해야 하는 것을 피하기 위해 이 알고리즘은 가능한 모든 루트(가능한 루트는 zval 변수 컨테이너)를 루트 버퍼(루트 버퍼)(보라색으로 표시), 이는 또한 가능한 각 가비지 루트가 버퍼에 한 번만 나타나는 것을 보장합니다. 가비지 수집은 루트 버퍼가 가득 찬 경우에만 버퍼 내의 모든 다른 변수 컨테이너에서 수행됩니다. 위 이미지의 A단계를 살펴보세요.

B 단계에서 알고리즘은 깊이 우선 검색을 사용하여 가능한 모든 근을 찾은 후 동일한 변수 컨테이너가 감소하지 않도록 각 변수 컨테이너의 참조 카운트를 "1"씩 감소시킵니다. "1"은 "1"에서 뺀 값으로 회색으로 표시됩니다. C 단계에서 알고리즘은 다시 각 루트 노드에 대해 깊이 우선 검색을 사용하여 각 변수 컨테이너의 참조 카운트를 확인합니다. 참조 횟수가 0이면 변수 컨테이너는 흰색(다이어그램에서는 파란색)으로 표시됩니다. 참조 카운트가 0보다 큰 경우, 이 시점에서 깊이 우선 탐색을 사용하여 참조 카운트를 "1"씩 감소시키는 작업(즉, 참조 카운트를 "1"씩 증가)을 재개한 다음, 검은색. 마지막 D 단계에서 알고리즘은 루트 버퍼를 순회하여 거기에서 변수 컨테이너 루트(zval 루트)를 제거하는 동시에 이전 단계에서 흰색으로 표시된 변수 컨테이너가 있는지 확인합니다. 흰색으로 표시된 각 변수 컨테이너가 지워집니다.

이제 이 알고리즘에 대한 기본적인 이해를 마쳤으니, 다시 돌아가 이것이 PHP와 어떻게 통합되는지 살펴보겠습니다. 기본적으로 PHP의 가비지 수집 메커니즘은 켜져 있으며 이를 수정할 수 있는 php.ini 설정인 zend.enable_gc가 있습니다.

가비지 수집 메커니즘이 켜져 있으면 루트 버퍼가 가득 찰 때마다 위에서 설명한 루프 검색 알고리즘이 실행됩니다. 루트 캐시 영역은 고정된 크기를 가지며 10,000개의 가능한 루트를 저장할 수 있습니다. 물론 PHP 소스 파일 Zend/zend_gc.c에서 상수 GC_ROOT_BUFFER_MAX_ENTRIES를 수정한 다음 PHP를 다시 컴파일하여 이 10,000개의 값을 수정할 수 있습니다. 가비지 수집이 꺼지면 루프 검색 알고리즘이 실행되지 않습니다. 그러나 구성에서 가비지 수집이 활성화되었는지 여부에 관계없이 루트가 항상 루트 버퍼에 존재할 수 있습니다.

가비지 수집 메커니즘이 꺼진 경우 루트 버퍼가 가능한 루트로 가득 차면 더 많은 가능한 루트가 기록되지 않습니다. 기록되지 않은 가능한 루트는 이 알고리즘으로 분석 및 처리되지 않습니다. 순환 참조 순환의 일부인 경우에는 지워지지 않으며 메모리 누수가 발생합니다.

가비지 수집이 불가능한 경우에도 가능한 루트를 기록하는 이유는 가능한 루트를 찾을 때마다 가비지 수집이 켜져 있는지 확인하는 것보다 가능한 루트를 기록하는 것이 더 빠르기 때문입니다. 그러나 가비지 수집 및 분석 메커니즘 자체에는 많은 시간이 걸립니다.

zend.enable_gc 구성을 수정하는 것 외에도 gc_enable() 및 gc_disable() 함수를 각각 호출하여 가비지 수집 메커니즘을 켜거나 끌 수도 있습니다. 이러한 함수를 호출하는 것은 가비지 수집 메커니즘을 켜거나 끄기 위해 구성 항목을 수정하는 것과 동일한 효과를 갖습니다. 루트 버퍼가 가득 차지 않은 경우에도 주기적으로 수집을 강제하는 기능. 이 목적으로 gc_collect_cycles() 함수를 호출할 수 있습니다. 이 함수는 이 알고리즘을 사용하여 재활용된 주기 수를 반환합니다.

가비지 수집을 켜고 끄고 자율 초기화를 허용하는 이유는 애플리케이션의 일부 부분이 시간에 민감할 수 있기 때문입니다. 이 경우 가비지 수집을 사용하고 싶지 않을 것입니다. 물론 애플리케이션의 특정 부분에 대해 가비지 수집을 끄면 메모리 누수가 발생할 위험이 있습니다. 일부 루트는 제한된 루트 버퍼에 맞지 않을 수 있기 때문입니다. 따라서 gc_disable() 함수를 호출하여 메모리를 해제하기 직전에 gc_collect_cycles() 함수를 먼저 호출하는 것이 현명할 수 있습니다. 이렇게 하면 루트 버퍼에 저장된 모든 가능한 루트가 지워지기 때문에 가비지 수집 메커니즘이 꺼지면 빈 버퍼를 남겨서 가능한 루트를 저장할 더 많은 공간을 확보할 수 있습니다.


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