구현 지침
1. 개체에 참조 카운터를 추가하면 참조 카운터의 값이 매번 증가합니다. 참조가 유효하지 않게 될 때마다 카운터는 1씩 감소합니다.
변수 값의 참조 횟수가 1만큼 감소하여 0이 되면 해당 값은 해제되며 가비지가 아닙니다. 가비지 수집기는 이를 처리하지 않습니다.
변수 값의 참조 횟수가 1만큼 감소한 후 0보다 큰 경우 해당 값은 해제할 수 없는 것으로 간주되어 가비지가 될 수 있습니다.
2. 쓰레기 수집기는 발생 가능한 쓰레기를 수집한 후 일정량에 도달하면 쓰레기 식별 프로그램을 시작하고 실제 쓰레기를 배출합니다.
예
<?php // PHP 가비지 수집 메커니즘 사례: PHP 매뉴얼을 참조하세요. //----------------------스칼라 유형--------- // 팁: 각 PHP 변수는 변수의 유형과 값을 포함하는 "zval"이라는 변수 컨테이너에 존재합니다. "is_ref": 참조 변수인지 여부, "refcount": 참조 횟수 // 예: 새 zval 컨테이너 생성 $a = 'new string'; // 예: zval 컨테이너 정보 표시 xdebug_debug_zval('a') // a: (refcount=1, is_ref=0),string 'new string' (length=10) // 예: zval 컨테이너의 참조 횟수를 늘립니다. $c = $b = $a; xdebug_debug_zval('a'); // a:(refcount=3, is_ref=0),string '새 문자열' (길이=10) xdebug_debug_zval('b'); // b:(refcount=3, is_ref=0),string '새 문자열' (길이=10) xdebug_debug_zval('c'); // c:(refcount=3, is_ref=0),string '새 문자열' (길이=10) // 팁: PHP는 생성된 변수 컨테이너가 필요하지 않을 때 복사하지 않기 때문에 현재 컨테이너는 하나만 있습니다. // 이때 이 변수 컨테이너는 변수 a, 변수 b 및 변수 c와 연결됩니다. unset($b); // 예: 참조 횟수 감소 xdebug_debug_zval('a') // a:(refcount=2, is_ref=0),string 'new string' (길이=10) // 팁: unset 변수를 삭제하면 refcount 변수 개수가 1씩 감소합니다. 이때 $a와 $b만 변수 컨테이너를 가리킵니다. 설정되지 않음($a); 설정 해제($c); var_dump($a); // Tip: 이때 recount는 0이 되고 변수는 삭제된다. // recount가 0이 되면 해당 타입과 값을 담고 있는 변수 컨테이너가 메모리에서 삭제된다. //---------복합 유형------------- echo '-------------복합 유형------------<br/>'; $a = 배열( '이름' => '후배', '나이' => 18 ); xdebug_debug_zval('a'); // a:(refcount=1, is_ref=0), // 배열 (크기=2) // '이름' => (refcount=1, is_ref=0),string 'junior' (길이=6) // '나이' => (refcount=1, is_ref=0),int 18 // 예: 배열에 기존 요소를 추가합니다. $a['love'] = $a['name']; xdebug_debug_zval('a'); // a:(refcount=1, is_ref=0), // 배열 (크기=3) // '이름' => (refcount=2, is_ref=0),string 'junior' (길이=6) // '나이' => (refcount=1, is_ref=0),int 18 // 'love' => (refcount=2, is_ref=0),string 'junior' (길이=6) // $a = array('one'); // xdebug_debug_zval('a'); // // $b = &$a; // $c = $a; // $b = &$c; // xdebug_debug_zval('b'); // xdebug_debug_zval('c'); // xdebug_debug_zval('a'); // 변수 컨테이너 문제 정리 echo '------------메모리 누수 문제------------<br/>'; $a = 배열('하나'); xdebug_debug_zval('a'); // a:(refcount=1, is_ref=0), // 배열 (크기=1) // 0 => (refcount=1, is_ref=0),string 'one' (길이=3) $a[] = &$a; xdebug_debug_zval('a'); // a:(refcount=2, is_ref=1), // 배열 (크기=2) // 0 => (refcount=1, is_ref=0),string 'one' (길이=3) // 1 => (참조 개수=2, is_ref=1), // &배열 // 설정 해제($a); // (refcount=1, is_ref=1)=배열( // 0 => (refcount=1, is_ref=0)='1', // 1 => (참조 개수=1, is_ref=1)=... // ) // 팁: unset($a) 후에는 이 구조(즉, 변수 컨테이너)를 가리키는 범위에 더 이상 기호가 없더라도 참조 횟수가 1씩 감소합니다. // 배열 요소 "1"은 여전히 배열 자체를 가리키므로 이 컨테이너는 지울 수 없습니다. // 이를 가리키는 다른 기호가 없으므로 사용자는 이 구조를 지울 수 없으며 메모리 누수가 발생합니다. // 다행히도 , PHP는 이 데이터 구조가 스크립트 실행이 끝나면 지워지지만 PHP가 이를 지우기 전에 많은 메모리가 소비됩니다. // 객체에서도 같은 일이 발생합니다. 실제로 객체는 항상 암시적으로 참조되기 때문에 객체에서 발생할 가능성이 더 높습니다.
위 내용은 PHP 참조 카운팅이 가비지 수집을 구현하는 방법입니다. 모든 사람에게 도움이 되기를 바랍니다.