우선 일반적인 유형의 변수(int, float, boolean)일 경우 실행 시 unset을 직접 삭제한다는 설명이다.
PHP 폐기물 회수 메커니즘(Garbage Conllector 약칭 GC)이 PHP에서 어떤 변수가 이 개체를 가리키지 않을 때 이 쌍마치 쓰레기 같다. PHP는 그것을 메모리에서 파괴한다. 이것은 메모리 오버플로를 방지하기 위한 PHP의 GC 폐기물 처리 장치이다.PHP 스레드가 종료되면 현재 사용 중인 모든 메모리 공간은 파기되며 현재 프로그램의 모든 객체는 동시에 파기됩니다.
php7의 쓰레기 수거는 쓰레기 수거기와 쓰레기 수거 알고리즘 두 가지다.
쓰레기 수집기, 방금 언급한 쓰레기일 수 있는 요소를 재활용 풀에 수집합니다. 즉, 변수의 zend_refcount에 대한 정보를 재활용합니다.연못 가운데. 휴지통의 값이 일정액에 도달하면 일괄 처리하겠습니다.
처리 과정은 비교적 간단하다.
재활용 풀의 모든 변수를 지나가고, 각 변수에 따라 각 멤버를 지나갑니다. 만약 멤버가 중첩되어 있다면 계속 건너뜁니다.그리고 멤버들 다 시뮬레이션 해봤어요 refcount-1이 때 외부 변수의 참조 수가 0이 되면그러면 쓰레기로 간주할 수 있다.0보다 크면 참조 수를 복원하고 휴지통에서 꺼내십시오.
인용 계수 기본 지식
각 PHP 변수에는 'zval'이라는 변수 컨테이너가 존재한다.변수의 유형과 값을 포함하는 zval 변수 컨테이너입니다. 두 바이트의 양입니다.외부 정보, 첫 번째는 'is_ref'입니다. 이 변수가 참조 집합(reference set)인지 여부를 나타내는 bool 값입니다.이 바이트를 통해서만 PHP 엔진은 일반 변수와 인용 변수를 구분할 수 있다.php를 통해 사용자 정의 참조를 사용할 수 있기 때문에 zval 변수 컨테이너에는 메모리 사용을 최적화하는 내부 참조 계수 메커니즘이 있다.두 번째 추가 바이트는 이 zval 변수 컨테이너를 가리키는 변수를 나타내는 "refcount"입니다.즉 symbol) 개수다.
예를 들어:
<?php
$hxg = "나쁜 놈";
?>
상기 변수 hxg는 현재 작용 영역에서 생성된다.그리고 유형이 string이고 값이 new string인 변수 컨테이너를 생성한다.이때 'is_ref'는 사용자 정의 참조가 생성되지 않았기 때문에 FALSE로 설정됩니다.'refcount'는 1로 설정되어 있으며, 여기서 단 하나의 변수만 이 변수 컨테이너를 사용하기 때문이다.그리고 'refcount'가 1일 때 'is_ref'는 항상 FALSE다.우리는 Xdebug를 설치하고 xdebug_debug_zval()을 호출하여 "refcount"와 "is_ref"의 값을 표시한다
<?php
xdebug_debug_zval('hxg');
?>
위 프로그램은 ===>hxg: (refcount=1, is_ref=0)='나쁜 꼬마'를 출력한다.변수에 값을 매기면 참조 횟수(refcount)가 증가한다.
예를 들어 인용 횟수를 늘립니다:
$hxg = "나쁜 놈";
$ztf = $hxg;
xdebug_debug_zval( 'hxg' );
위 프로그램은 ===>hxg: (refcount=2, is_ref=0)= '나쁜 꼬마'를 출력한다.
이 때 인용 횟수는 2가 됩니다. 같은 변수 컨테이너가 변수 a와 변수 b에 관련되기 때문입니다. 필요할 때 php는 복원되지 않습니다.생성된 변수 컨테이너를 만듭니다.변수 컨테이너는 "refcount"가 0이 되었을 때 파기됩니다. 변수 컨테이너에 연결된 모든 변수가 함수 실행 종료와 같은 영역에서 벗어나거나 변수에 함수 unset()을 호출하면 "refcount"가 1 감소합니다.
<?php
$hxg = "나쁜 놈;
$lj = $ztf = $hxg;
xdebug_debug_zval( 'hxg' );
unset( $ztf, $lj );
xdebug_debug_zval( 'hxg' );
?>
위의 프로그램 출력:
hxg: (re)fcount=3, is_ref=0)='나쁜놈'
hxg: (re)fcount=1, is_ref=0)='나쁜놈'
만약 우리가 지금 실행한다면 unset($hxg); 형식과 값을 포함하는 이 변수 컨테이너는 메모리에서 삭제됩니다.나누다.
복합형:
array와 object 유형의 변수는 구성원이나 속성을 자신의 기호 테이블에 저장한다.이는 다음 예에서 세 개의 zval 변수 컨테이너를 생성한다는 것을 의미한다.
<?php
$a = array( 'meaning' => 'life', 'number' => 42 );
xdebug_debug_zval( 'a' );
?>
위의 프로그램 출력:
a: (refc)ount=1, is_ref=0)=array (
'meaning'' => (refcount=1, is_ref=0)='life',
'number' => (refcount=1, is_ref=0)=42
이 세 개의 zval 변수 컨테이너는 다음과 같습니다. a, meaning, number."refcount"를 추가하고 줄이는 규칙은 위에서 언급한 것과 같습니다. 아래에 배열에 요소를 하나 더 추가하고 배열에 이미 존재하는 요소의 값을 설정합니다
<?php
$a = array( 'meaning' => 'life', 'number' => 42 );
$a['life'] = $a['meaning'];
xdebug_debug_zval( 'a' );
?>
위 프로그램 출력===>a: (refcount=1, is_ref=0)=array (
'meaning' => (refcount=2, is_ref=0)='life',
'number' = > (refcount=1, is_ref=0)=42,
'life' = > (refcount=2, is_ref=0)='life'
Xdebug의 출력은 'life' 값인 두 개의 zval 변수 컨테이너를 보여주지만, 실제로는 동일한 "refcount' 2의 zval 변수 컨테이너와 연결된 기존 배열 요소를 봅니다.
배열의 요소를 제거합니다. 이 요소는 도메인에서 변수를 제거하는 것과 같습니다. 삭제하면 배열의 요소가 있는 컨테이너의 "refcount" 값이 감소하며, "refcount" 값이 0일 때 이 컨테이너는 메모리에서 제거됩니다.나누다
<?php
$a = array( 'meaning' => 'life', 'number' => 42 );
$a['life'] = $a['meaning'];
unset( $a['meaning'], $a['number'] );
xdebug_debug_zval( 'a' );
?>
위 프로그램 출력===> a: (refcount=1, is_ref=0)=array (
'life' = > (refcount=1, is_ref=0)='life'
)
자, 지금부터 중요한 문제를 토론하겠습니다. 만약 배열이 있다면, 자신을 어떻게 다룰까요?
<?php
$a = array( 'one' );
$a[] =& $a;
xdebug_debug_zval( 'a' );
?>
위 프로그램 출력===>a: (refcount=2, is_ref=1)=array (
0 => (refcount=1, is_ref=0)='one',
1 => (refcount=2, is_ref=1)=…
)
배열 변수 (a) 이 배열의 두 번째 요소인 (1)이 가리키는 변수 컨테이너의 "refcount"는 2입니다.위의 출력 결과 중 "…"은 재귀적 조작이 발생했음을 의미하며, 이 경우 "…"는 원래의 배열을 가리킨다는 것이 명백하다.
PHP5.3.0 이후 순환 참조 문제를 해결합니다.
참조 카운트가 0으로 줄어들면 해당 변수 컨테이너가 삭제(free)되며 쓰레기가 아닙니다
zval의 인용수가 0보다 크면 쓰레기 주기가 된다.0이 아닌 값으로 인용 횟수를 줄일 때만 쓰레기 주기(garbage cycle)가 생긴다.둘째, 1회 쓰레기주기 동안 인용계수가 1을 감산하는지 여부를 검사하여그리고 어떤 변수 용기의 인용 횟수가 0인지 검사하여 보내드립니다.지금 어느 부분이 쓰레기입니까
A: 모든 가능한 루트(possible roots는 zval 변수 컨테이너)를 루트 버퍼(root buffer)에 넣어(보라색으로 표시) 각 가능한 쓰레기의 루트가 버퍼에 한 번만 나타나도록 한다.버퍼가 가득 차면 쓰레기 수거 작업을 한다.
B: 각 보라색 변수를 시뮬레이션에서 삭제하고, 알고리즘은 깊이 우선으로 각 노드에 포함된 zval을 1 빼기(클래스에 대한 트래버스에서는 상속 클래스와 자신의 두 대상 멤버 속성 테이블을 병합)하여 동일한 zval의 refcount에 대해 1 빼기 동작을 반복하지 않도록 합니다.작, zval의 refcount를 1 빼면 zval을 회색으로 표기한다.이 절차에서는 처음에는 노드 zval 자체가 1 빼기 동작을 하지 않지만 노드 zval에 포함된 zval이 노드 zval(루프 참조)을 가리키면 노드 zval을 1 빼기 동작을 해야 한다는 점을 강조할 필요가 있다.
C: 알고리즘은 각 노드에 포함된 zval의 값을 깊이 우선으로 다시 판단한다. zval의 refcount가 0이면 파란색(쓰레기를 나타낸다)으로 표시하고, zval의 refcount가 0보다 크면 이에 포함된 zval을 진행한다.refcount+1 조작, 이것은 비쓰레기 복원 조작, 그리고 이 zval의 색깔을 검정색으로 바꾼다.
D: 파란색 노드를 삭제합니다.
루트 캐시에는 10,000개의 가능한 루트를 저장할 수 있는 고정된 크기가 있습니다. 물론 당신은 PHP 소스 파일의 Zend/zend_gc.c에 있는 상수 GC_ROOT_BUFFER_MAX_ENTRIES를 수정한 다음 PHP를 다시 컴파일하여 이 10을 수정할 수 있습니다.000의 값.
물론 PHP는 GC를 수동으로 조작할 수 있는 함수를 준비했습니다.
gc_enable() 함수와 gc_disable() 함수를 각각 호출하여 쓰레기 수거 메커니즘을 켜고 끕니다.이러한 함수를 호출하는 것은 쓰레기 수거 장치를 켜거나 끌 때 설정 항목을 수정하는 것과 같습니다.루트 버퍼가 채워지지 않은 경우에도 사이클백을 강제 실행받아라.gc_collect_cycles() 함수를 호출할 수 있다.이 함수는 이 알고리즘을 사용하여 회수된 사이클 수를 반환합니다.
'개발 꿀팁 > PHP' 카테고리의 다른 글
PHP에서 시스템 명령 실행 (disable_functions 바이패스) (0) | 2022.07.15 |
---|---|
mariadb 간단한 소개와 PHP 환경 (0) | 2022.07.15 |
PHP 로케일 설정 (0) | 2022.07.15 |
PHP 배열이 연속 디지털 인덱스로 재설정되는 몇 가지 방법 (0) | 2022.07.15 |
php 배열 병합 및 키 값 보존 방법 (0) | 2022.07.15 |