PHP 참조 전달

WBOY
WBOY원래의
2016-07-28 08:26:43954검색

저도 PHP를 배우는 사람이지만 이전에는 PHP 내부의 가비지 수집 프로세스에 대해 잘 몰랐습니다. 메모리 오버플로를 방지하기 위해 코드에서 unset, null, mysql_close, __destruct 및 기타 함수를 사용하여 객체를 해제했습니다. 나는 인터넷의 GG에서 다음 지침을 찾아 기록했습니다. "PHP는 자동으로 메모리를 관리하고 더 이상 필요하지 않은 개체를 지울 수 있습니다. PHP는 참조 카운팅이라는 간단한 가비지 수집 메커니즘을 사용합니다. 각 개체에 참조 카운터가 포함될 때마다 그리고 각 참조는 개체에 연결됩니다. 참조가 생활 공간을 벗어나거나 NULL로 설정되면 카운터는 1씩 감소합니다. 개체의 참조 카운터가 0이 되면 PHP는 이 개체가 더 이상 존재하지 않는다는 것을 알게 됩니다. 필요하고 그것이 차지하는 메모리 공간이 해제됩니다.”
우리 모두 알고 있듯이 PHP 엔진 자체는 C로 작성되었습니다. C를 언급할 때 GC(가비지 수집)를 언급해야 합니다. PHP 매뉴얼을 통해 PHP 엔진이 자동으로 GC 작업을 수행한다는 것을 알고 있습니다. 질문하지 않을 수 없습니다. & 참조 작업이 포인터입니까? unset()을 사용하여 변수를 설정하면 실제로 재활용됩니까? 주의 깊게 분석해 보면 그것이 단순하고 일반적이지 않다는 것을 알게 될 것입니다. 아마도 누군가는 PHP 소스 코드를 보면 알 수 있을 것입니다. 이 문제는 반드시 해결될 것입니다.그러나 이 글에서는 겉으로 보기에 평범해 보이는 PHP 자체에 대해서만 분석하겠습니다.물론, 레벨이 제한되어 있고 누락된 부분도 있을 수 있습니다.
먼저 가장 간단한 실행 프로세스인 예를 살펴보겠습니다.
예제 1: gc.php
error_reporting(E_ALL); a = '저는 테스트입니다.';
$b = & $a;
echo $b ." "
말할 필요도 없습니다.% php -f gc.php 출력 결과 매우 명확함:
hy0kl% php -f gc.php
테스트 중입니다.
알겠습니다. 다음:
예 2:
error_reporting(E_ALL)
$a = '나는 테스트입니다.';
$b = & $a
$b = '바꿀까요?'
echo $a ." "
echo $ b ." ";
?>
실행 결과는 여전히 확실합니다:
hy0kl% php -f gc.php
바꿀까요?
jun? 참조:
예 3:
error_reporting(E_ALL)
$a = '나는 테스트입니다.'
$b = & $a; unset($a);
echo $a ." ";
echo $b ."
?>
hy0kl% php - f gc.php
주의: 정의되지 않은 변수: /usr/local/www/apache22/data/test/gc.php 8행의 a
저는 테스트 중입니다.
좀 혼란스럽나요?
다시 살펴보세요:
예제 4:
error_reporting(E_ALL); 나는 테스트 중입니다.'; $b = & $a;
echo $a ." ";"
? ;
사실 예제 3을 이해하시면 비슷합니다.
hy0kl% php -f gc.php
저는 테스트입니다.
주의: 정의되지 않은 변수: /usr/ 9행의 local/www/apache22/data/test/gc.php
한 번 보세요:
예 5:
error_reporting(E_ALL);
$a = '나는 테스트입니다.'
$b = & $ a ;
$a = null;
echo '$a = '.$b ."
첫 번째 폭력의 느낌은 무엇입니까?
hy0kl% php -f gc.php
$a =
$b =
네, 깊이 이해한 결과입니다. PHP를 이해하는 사람이라면 이상하게 생각하지 않을 것입니다. 솔직히 이 코드를 처음 실행했을 때 놀랐지만, PHP GC에 대한 더 깊은 이해를 제공했습니다. 자연스럽게 이해하기가 더 쉽습니다.
예 6:
error_reporting(E_ALL);
$a = '나는 테스트입니다.'
$b = & $a
$b; null;
echo '$a = '.$a ." ";
echo '$b = '.$b ."
?> 결과에는 독자를 위한 세부정보가 없으므로 시간이 나면 이 창을 닫고 다시 오셔도 됩니다.
GC 및 참조를 자세히 분석해 보겠습니다.
1. 간단히 말하면, 이 프로세스는 메모리에 공간을 열고 그 안에 테스트 중인 문자열을 저장하는 것입니다. PHP 내부에는 각 메모리 블록의 참조 카운트를 기록하는 기호 테이블이 있으며, 이는 여기에 저장됩니다. time 블록 메모리의 참조 횟수가 1 증가하고 $a라는 라벨(변수)을 사용하여 이 메모리 블록을 가리키므로 라벨 이름에 따라 메모리를 조작하는 것이 편리합니다.
2. 변수 $a에 대한 수행 및 작업 내 이해는 $a가 가리키는 메모리를 찾고 $b에 대해 동일한 참조 지점을 설정하고 테스트 중인 문자열의 메모리 블록을 The 기호에 저장하는 것입니다. 즉, 스크립트가 이 라인에 도달하면 I am test.라는 문자열을 저장하는 메모리가 두 번 참조됩니다. 포인터의 경우, PHP에는 포인터 개념이 없습니다. 동시에 일부 사람들은 UNIX와 유사한 파일 소프트 링크를 제안했습니다. 이는 어느 정도 이해할 수 있습니다. 제가 테스트하는 문자를 저장하는 메모리는 우리의 실제 항목 중 하나입니다. 파일, 변수 $a 및 $b는 실제 파일에 대해 설정된 소프트 링크이지만 동일한 실제 파일을 가리키므로 예제 2에서 $b에 값이 할당되면 $a의 값도 변경되는 것을 알 수 있습니다. 소프트 링크는 파일을 유사하게 작동합니다.
3. 예제 3과 4에서는 unset() 작업을 수행한 결과를 보면 unset()은 원래 가리키는 메모리에 대한 참조만 끊는다는 것을 알 수 있습니다. 변수 자체를 null 참조가 정의되지 않았으며 호출 중에 알림이 발행되었으며 기호 테이블에 있는 해당 메모리 조각의 참조 카운트가 1씩 감소했으며 이 조각을 가리키는 다른 변수에는 영향을 미치지 않았습니다. 즉, 메모리 조각이 기호 테이블에 있을 때만 참조 횟수가 0에 도달하면 PHP 엔진이 이 메모리를 회수합니다.
PHP 매뉴얼
4.0.0 unset()은 표현식이 되었습니다. (PHP 3에서는 unset()이 항상 1을 반환합니다.)
이것이 무엇을 의미하나요?
다음 코드를 보세요. 결과 :
error_reporting(E_ALL)
$a = '나는 테스트입니다.'
$b = & $a;unset($a);
unset($a);
echo '$a = '.' "
echo '$b = '. $b ." ";
?>
hy0kl% php -f gc.php
주의: 정의되지 않은 변수: /usr/local/www/apache22/data/test/gc.php 10번째 줄
$a =
$b = 테스트 중입니다.
첫 번째 unset() 작업에서 포인터 연결이 끊어졌으므로 후속 작업으로 인해 기호 테이블에 메모리 참조 횟수가 발생하지 않습니다.
4. 예제 5, 6을 통해 null을 할당하는 작업은 변수가 가리키는 메모리의 기호 번호의 참조 횟수를 0으로 직접 설정한다는 결론을 내릴 수 있습니다. 그러면 이 메모리 조각은 당연히 엔진에 의해 재활용되었으며, 언제 다시 사용될지는 알 수 없으며, 다른 정보를 즉시 저장하는 데 사용될 수도 있고, 결코 다시 사용되지 않을 수도 있습니다. 더 이상 메모리를 작동할 수 없으며 메모리가 회수되었으며 이를 호출하려는 모든 변수는 null을 반환합니다.
error_reporting(E_ALL);
$a = '나는 테스트입니다.'
$b = & $a
$b = null; '$a = '.$a ." "
echo '$b = '.$b ." "
if (null === $a)
{
echo '$ a는 null입니다.'; else
{
echo '$a의 유형을 알 수 없습니다.'
}
?> php
$a =
$b =
$a는 null입니다.
요약하자면, 오픈 소스 제품의 소스 코드를 볼 때 상대적으로 큰 값이 자주 나타나는 이유를 충분히 설명합니다. 임시 변수나 사용 후 호출되지 않는 재사용 정보는 집중되거나 null로 표시됩니다. 이는 UNIX에서 실제 파일을 직접 죽이는 것과 같으며 이를 가리키는 모든 소프트 링크는 자연스럽게 빈 링크가 됩니다.
위 내용은 내용의 측면을 포함하여 PHP의 참조 전달을 소개합니다. PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.


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