시간이 변경되고 그에 따라 용어가 변경됩니다. 오늘날 우리는이를 "쓰레기 재활용"대신 "PHP 자원 재활용"이라고 부를 수 있습니다. 이것은 본질을 더 밀접하게 반영합니다. 단순히 버려지는 것이 아니라 더 이상 사용되지 않는 리소스를 재사용합니다. 그러나 "쓰레기 재활용"의 역사를 따르는 것이 더 일반적입니다.
코어 포인트 :
PHP의 쓰레기 수집 메커니즘은 스코프 엔드, 참조 계산 및 공식적인 쓰레기 수집의 세 가지 레벨로 나뉩니다. 범위가 끝나면 함수, 스크립트 또는 세션의 리소스가 지워집니다. 참조 수 변수를 사용하여 엔티티의 수를 추적합니다. PHP 5.3에 도입 된 공식적인 쓰레기 수집 메커니즘은 기준 수가 0이 아닌 경우를 다루지 만 더 감소 할 수있는 경우를 다룹니다.
PHP의 쓰레기 수집 메커니즘은 항상 활성화되어 있지만 수동으로 제어 할 수 있습니다. php.ini 파일 또는 gc_enable () 및 gc_disable () 함수를 사용하여 스크립트에서 비활성화 할 수 있습니다. GC_COLLECT_CYCLES () 함수를 사용하면 수동 쓰레기 수집을 시작할 수 있으며 PHP 소스 코드에서 루트 버퍼 크기를 수정할 수 있습니다.
쓰레기 수집은 메모리 할당을 관리하고 메모리 누출을 방지하는 데 도움이되지만 리소스 집약적 특성은 성능에도 영향을 줄 수 있습니다. 따라서, 가비지 컬렉션이 메모리 누출을 방지하는 데 중요한 장기 스크립트 또는 끝없는 스크립트에서 전략적으로 사용해야합니다.
좋은 프로그래밍 관행은 쓰레기 수집을 최적화하는 데 도움이됩니다. 여기에는 글로벌 변수 최소화 또는 제거, 범위에 대한 바인딩 변수, 배열 중첩 또는 객체 참조 객체의 상황에주의를 기울이는 것이 포함됩니다. 이러한 상황은 메모리 누출로 이어질 수 있으며 공식적인 쓰레기 수집 메커니즘의 주요 목표이기 때문입니다.
-
프로그램 생성 쓰레기 생성 - 프로그램은 자원, 때로는 작은 자원, 때로는 큰 자원을 사용합니다. 예를 들어, 데이터 필드. 프로그램은 데이터 필드 (예 : 일련 번호)를 정의하여 프로그램에서 사용할 수 있습니다. 일단 정의되면,이 데이터 필드는 메모리 공간, 아마도 몇 바이트 만 사용하지만 여전히 공간을 차지합니다. 각 기계 또는 프로그래밍 환경에는 가용 공간이 제한되어 있으므로 나머지 공간은이 필드가 차지하는 공간의 양을 줄입니다. 프로그램이 끝나면 프로그램과 소비되는 공간이 사라지고 가용 한 공간이 최대 크기로 복원됩니다. 그러나 프로그램이 끝나지 않으면 어떻게됩니까? 나는이 프로그램들 중 일부를 전에 작성했습니다. 그들은 아름다운 걸작이며 워크숍에서 다른 사람들이 내가 만들었 음을 알 때마다 항상 행복합니다. 큰 IBM 컴퓨터를 스스로 내려 놓는 것보다 더 나은 능력을 나타내는 것은 없으며, 주변 구획에서 한 사람은“이봐, 시스템에 문제가 있습니까?” 당신에게서 관심을 돌리십시오. 그러나 일부 프로그램은 Daemons 및 기타 프로그램과 같은 영원히 실행되도록 설계되었습니다. 그들이 달리면 그들이 생성하는 쓰레기의 양이 계속 자랄 수 있습니다. 잠긴 자원이 크면 시스템에 실제로 부정적인 영향을 미칩니다. 따라서 각 언어는 고아 자원을 지우고 다른 사용자가 사용할 수 있도록하는 방법이 있어야하며 사용 가능한 시스템 공간의 총량이 동일하게 유지되어야합니다. 다행히도 PHP는 쓰레기 제거를 위해 3 층 방법을 사용합니다.
첫 번째 레이어 - 스코프의
우선, 대부분의 언어와 마찬가지로 범위가 끝날 때마다 해당 범위 내의 모든 것이 파괴되고 할당 된 리소스가 해제됩니다. 스코프는 함수, 스크립트, 세션 등을 포함 할 수 있습니다. 스코프가 끝나면 모든 것이 끝나는 모든 것이 끝납니다. 물론 UnSet () 함수를 사용하여 언제든지 리소스를 확보 할 수 있습니다. 이것은 기능과 메소드가 스코프를 설정하고 특정 메모리 사용이 시작되고 끝나는시기를 지정하고 무엇이 존재하는지 제한하기 때문에 매우 중요한 이유 중 하나입니다. 글로벌 엔티티가 아니라 가능한 한 사용해야합니다.
두 번째 레이어 - Citation Count
둘째, 대부분의 스크립팅 언어와 마찬가지로 PHP는 참조 카운팅이라는 기술을 사용하여 주어진 변수를 사용하는 엔티티 수를 추적합니다. PHP 스크립트에서 변수를 생성 할 때 PHP는 변수에 할당 된 값과 다른 두 가지 정보 (IS_REF 및 refCount)로 구성된 ZVAL이라는 작은 "컨테이너"를 만듭니다. ZVAL 컨테이너는 테이블에 저장되며 각 범위 (스크립트, 기능, 메소드 등)에는 테이블이 있습니다. IS_REF는 변수가 참조 세트의 일부인지를 나타내는 간단한 true/false 값이므로 PHP가 간단한 변수인지 참조인지 판단하는 데 도움이됩니다. refcount는이 값을 사용하는 다른 변수의 수를 나타내는 숫자 값을 보유하기 때문에 더 흥미 롭습니다. 즉, 변수 $ dave = 6을 정의하면 refcount가 1으로 설정됩니다. $ programmer = $ dave라고 말하면 refcount는 2로 증가합니다. PHP는 값 6에 대한 두 번째 ZVAL을 만들지 않는다는 것을 알고 있습니다. 이 refcount는 프로그램이 종료되거나 함수의 범위를 떠날 때 또는 unset ()를 사용할 때 줄어 듭니다. refcount가 0에 도달하면 Zval이 파괴되고 그 메모리가 이제 해방됩니다. 물론 이것은 간단한 변수의 간단한 예입니다. 배열이나 객체에 대해 이야기 할 때, 배열의 여러 값의 요소 값에 대해 여러 zref가 생성되기 때문에 상황이 훨씬 더 복잡하지만 기본 처리는 동일합니다. 그러나 더 복잡한 PHP 스크립트에서 자주 발생하는 다른 배열에서 배열을 사용하면 문제가 발생합니다. 이 경우 원래 배열 값이 설정되면 배열 값의 refcount가 1으로 설정된 다음 배열이 다른 배열과 연관되면 refcount가 2로 증가합니다. 두 번째 배열의 사용 범위가 끝나면 refcount는 1만큼 감소합니다. 우리는 이제 값 자체가 더 이상 아무것도 관련이없는 상황에 처해 있지만, 컨테이너 (ZVAL)의 refcount는 여전히 0보다 큽니다. 최종 결과는 원래 배열로 표시되는 스토리지가 해제되지 않으며 이제는 메모리 양을 사용할 수 없다는 것입니다. 종종 우리는이 손실 된 저장소가 작지만 일반적으로 그렇지 않습니다. 요즘 배열은 매우 큰 일이 될 수 있으며, 발생하는 스크립트가 거의 지속적으로 실행되는 데몬 또는 다른 기능이라면 특히 문제가됩니다. 이 경우, 그 결과 "메모리 누출"은 성능 및 서버의 운영 기능에 치명적인 결과를 초래할 수 있습니다.
3 층 - 형식 쓰레기 재활용 분명히, 참조 수를 기반으로 한 지우기에는 한계가 있지만 운 좋게도 PHP 5.3 은이 상황에 도움이되는 또 다른 옵션을 제공합니다. 우리가 쓰레기 수거 사이클을 해결하려는 구체적인 경우는 ZVal이 감소하지만 여전히 0이 아닌 경우입니다. 기본적으로, 루프는 어떤 값을 더 감소시킬 수 있는지 확인한 다음 0으로 값을 방출합니다. 실제로 발생하는 것은 PHP가 모든 루트 컨테이너 (ZVAL)를 추적한다는 것입니다. 쓰레기 수집이 켜져 있는지 여부에 관계없이 이루어집니다 (쓰레기 수집이 켜져 있는지 묻지 않으면 서이 작업을 수행해야하기 때문에). 이 루트 버퍼는 최대 10,000 개의 루트를 유지할 수 있지만 (고정 크기이지만 변경할 수 있음) 변경할 수 있습니다. 그것이 채워지면 쓰레기 수집 메커니즘이 시작 하여이 버퍼를 분석하기 시작합니다. GC 루틴이 가장 먼저하는 일은 루트 버퍼를 반복하고 모든 ZVAL 카운트를 1로 줄이는 것입니다. 이 작업을 수행 할 때는 각 태그를 검사 표시와 같은 작은 태그로 표시하여 루트를 한 번만 줄입니다. 그런 다음 반복하고 (이번에는 작은 물결 선을 사용하여) 카운트의 감소가 0 인 모든 Zvals를 표시합니다. 0이 아닌 값은 원래 값으로 돌아갈 수 있도록 증가합니다. 마지막으로, 다시 스크롤하고 버퍼에서 0이 아닌 Zval을 지우고 0 refcount의 값으로 상점을 제거합니다. Garbage Collection은 항상 PHP에서 활성화되어 있지만 Php.ini 파일에서 Directive Zend.enable_gc를 사용하여 꺼질 수 있습니다. 또는 gc_enable () 및 gc_disable () 함수를 호출하여 스크립트에서이를 수행 할 수 있습니다. 위에서 언급했듯이 쓰레기 수집이 활성화되면 루트가 가득 차면 실행되지만이 설정을 무시하고 gc_collect_cycles () 함수를 사용하여 컬렉션을 실행할 수 있습니다. 또한 PHP 소스 코드에서 Zend/Zend_gc.c의 gc_root_buffer_max_entries 값을 사용하여 루트 버퍼의 크기를 수정할 수 있습니다. 대체로,이를 통해 GC가 실행되는지,시기, 위치 여부와 위치를 제어 할 수 있습니다. 이는 약간의 자원 집약적이므로 마음대로 운영하는 종류가 아닐 수도 있기 때문에 좋은 일입니다.
사용시기 쓰레기 수집은 성능에 영향을 줄 수 있으므로 시간을 내야하는시기를 결정하는 것이 좋습니다. 먼저 공개적으로 실행하지 않으면 (GC_Collect_Cycles () 함수 사용)를 사용하지 않으면 루트 테이블 (10,000 개의 항목)이 채워지기 전에 공식적인 쓰레기 수집이 발생하지 않으며,이 테이블이 범위 레벨에 있기 때문에 작은 원한이라는 소규모의 경우 ' t는 기능으로 발생합니다. 작은 스크립트에서 사용해야합니까? 그것은 당신에게 달려 있습니다. 가비지 컬렉션과 같은 운영을 실행하는 것은 나쁜 일이라고 말하기는 어렵지만, 시작하고 끝나고 사라지는 작고 빠르게 실행되는 스크립트가 있다면 많은 보상이 없을 수 있습니다. 그러나 서버가 지속적으로 유지되는 많은 작은 스크립트를 실행하면 노력할 가치가있을 수 있습니다. 실제로 알 수있는 유일한 방법은 응용 프로그램의 벤치 마크를 설정하고이를 보는 것입니다. 물론, 장기 실행 스크립트, 특히 결코 끝나지 않는 스크립트가 있다면, 위에서 논의한 메모리 누출을 방지하려면 쓰레기 수집이 중요합니다. 아마도 가장 중요한 것은 글로벌 변수를 최소화하거나 제거하고 변수를 범위에 바인딩 할 수 있도록 항상 우수한 프로그래밍 안내서를 따르려고 노력해야한다. 스크립트의 끝에 없습니다. 또한 배열 또는 객체 참조 객체가 배열에서 사용되는시기를 알아야합니다.이 상황은 메모리 누출로 이어질 수 있으며 공식적인 쓰레기 수집 프로세스의 실제 목표입니다.
Fotolia의 사진
PHP 쓰레기 재활용 FAQ (FAQ)
(FAQ 부분은 기사가 너무 길고 의사 원리 목표와 일치하지 않기 때문에 여기서 생략됩니다. FAQ 부분의 내용은 원래 텍스트와 매우 일치하고, 의사 원리는 어렵고 원래 의미는 어렵습니다. 수정 후에 변경 될 수 있습니다.)
위 내용은 PHP 마스터 | PHP의 쓰레기 수집을 더 잘 이해합니다의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!