> 백엔드 개발 > PHP 튜토리얼 > PHP 가비지 수집 메커니즘과 관련된 문제

PHP 가비지 수집 메커니즘과 관련된 문제

墨辰丷
풀어 주다: 2023-03-30 14:40:01
원래의
1394명이 탐색했습니다.

이 글은 주로 PHP 가비지 수집 메커니즘과 관련된 문제를 소개합니다. 관심 있는 친구들이 참고하면 도움이 될 것입니다.

PHP의 기본 GC 개념PHP 언어에도 다른 언어와 마찬가지로 가비지 수집 메커니즘이 있습니다. 그래서 오늘 우리가 여러분에게 설명하고 싶은 것은 PHP 가비지 수집 메커니즘과 관련이 있습니다. 그것이 모두에게 도움이 되기를 바랍니다. PHP strtotime 애플리케이션 경험 PHP memory_get_usage() 메모리 관리 PHP 설정되지 않은 전역 변수 사용 문제 자세한 설명 PHP unset() 함수는 변수를 파괴하여 PHP 전체 사이트 권한 확인을 신속하게 구현하도록 가르칩니다. 1. PHP 가비지 수집 메커니즘(GC라고 하는 가비지 수집기) ) PHP에서 이 개체를 가리키는 변수가 없으면 이 개체는 가비지가 됩니다. PHP는 메모리에서 이를 파괴합니다. 이는 메모리 오버플로를 방지하기 위한 PHP의 GC 가비지 처리 메커니즘입니다. PHP 스레드가 종료되면 현재 점유된 모든 메모리 공간이 소멸되고, 현재 프로그램의 모든 객체도 동시에 소멸됩니다. GC 프로세스는 일반적으로 각 SESSION에서 실행을 시작합니다. gc의 목적은 세션 파일이 만료된 후 자동으로 삭제하고 삭제하는 것입니다. 2. __destruct /unset __destruct() 소멸자는 가비지 개체가 재활용될 때 실행됩니다.
unset은 객체가 아닌 객체를 가리키는 변수를 파괴합니다. 3. 세션 및 PHP 가비지 수집 메커니즘 PHP의 작동 메커니즘으로 인해 세션 정보를 정기적으로 검사하고 유효한 요청이 발생하면 PHP는 전역 변수 session.gc_probability를 사용합니다. session .gc_pisor의 값은 GC 활성화 여부를 결정합니다. 기본적으로 session.gc_probability=1, session.gc_pisor =100은 GC를 시작할 가능성이 1%라는 의미입니다(즉, 100번에 1번의 gc만 있음). 요청) 100개 요청 중 하나로 시작됩니다.) PHP 가비지 수집 메커니즘의 작업은 모든 세션 정보를 스캔하고 현재 시간에서 세션의 마지막 수정 시간을 뺀 후 이를 session.gc_maxlifetime 매개변수와 비교하는 것입니다. .생존 시간이 gc_maxlifetime(기본값 24분)을 초과하면 세션이 삭제됩니다.
그러나 웹 서버에 여러 사이트가 있는 경우 GC가 세션을 처리할 때 예상치 못한 결과가 발생할 수 있습니다. 그 이유는 GC가 작동할 때 다른 사이트의 세션을 구분하지 못하기 때문입니다. 그러면 이 문제를 어떻게 해결할 수 있을까요?
1. session.save_path()를 사용하여 각 사이트의 세션을 전용 디렉터리에 저장합니다.
2. 당연히 PHP 가비지 수집 메커니즘의 시작 속도가 증가합니다. 그에 따라 시스템 성능도 향상되지만 권장되지 않습니다.
3. 코드에서 현재 세션의 수명을 확인하고 session_destroy()를 사용하여 삭제합니다.


참조 계산에 대한 기본 지식각 PHP 변수는 "zval"이라는 변수 컨테이너에 존재하며 변수의 유형과 값을 포함하는 것 외에도 2바이트의 추가 정보도 포함합니다. 이 변수가 참조 세트에 속하는지 여부를 식별하는 데 사용되는 bool 값인 "is_ref"입니다. PHP 엔진에서는 사용자가 & Custom 참조를 사용할 수 있으므로 일반 변수와 참조 변수를 구분할 수 있습니다. 메모리 사용을 최적화하기 위한 zval 변수 컨테이너의 내부 참조 계산 메커니즘입니다. 두 번째 추가 바이트는 이 zval 변수 컨테이너 번호를 가리키는 변수(기호라고도 함)를 나타내는 데 사용됩니다.

변수가 상수 값이 할당되면 다음 예와 같이 zval 변수 컨테이너가 생성됩니다.

  <?php 
  $a = "new string"; 
   
  ?>
로그인 후 복사


위 예에서 새 변수는 현재 범위에서 생성된 a이며 문자열 유형의 변수 컨테이너입니다. 추가 2바이트 정보에서는 사용자 정의 참조가 생성되지 않기 때문에 기본적으로 "is_ref"가 false로 설정됩니다. 이를 사용하는 변수가 하나만 있으므로 "refcount"는 1로 설정됩니다. 변수 컨테이너를 호출하여 변수 내용을 확인하세요.

  <?php 
  $a = "new string"; 
   
  xdebug_debug_zval(&#39;a&#39;); 
  ?>
로그인 후 복사


위 코드는 다음을 출력합니다:

  a: (refcount=1, is_ref=0)=&#39;new string&#39;
로그인 후 복사


변수 a

  <?php 
  $a = "new string"; 
   
  $b = $a; 
  xdebug_debug_zval(&#39;a&#39;); 
  ?>
로그인 후 복사


에 참조 카운트를 추가합니다. 위 코드는 다음을 출력합니다:

  a: (refcount=2, is_ref=0)=&#39;new string&#39;
로그인 후 복사


이때, 동일한 변수 컨테이너가 변수 a 및 변수 b와 연관되어 있으므로 참조 수는 2입니다. PHP는 필요하지 않은 경우 생성된 변수 컨테이너를 복사하지 않습니다. "refcount"가 파괴되면 변수 컨테이너가 0으로 변경됩니다. 특정 변수와 연결된 변수가 해당 범위를 벗어나거나(예: 함수 실행 종료) 변수에 대해 unset() 함수가 호출되면 "refcount"가 1만큼 감소합니다. 다음 예에서는 설명할 수 있습니다.

  <?php 
  $a = "new string"; 
  $b = $c = $a; 
  xdebug_debug_zval(&#39;a&#39;); 
  unset($b, $c); 
  xdebug_debug_zval(&#39;a&#39;); 
  ?>
로그인 후 복사


위 코드는 다음을 출력합니다:

  a: (refcount=3, is_ref=0)=&#39;new string&#39; a: (refcount=1, is_ref=0)=&#39;new string&#39;
로그인 후 복사


지금 unset($a)를 실행하면 $의 유형과 값을 포함하는 컨테이너가 메모리에서 삭제됩니다

컴파운드 유형

상황이 조금 나아집니다. 배열 및 객체와 같은 복합 유형을 고려하면 더 복잡합니다. 스칼라 유형의 값과 달리 배열 및 객체 유형의 변수는 해당 멤버 또는 속성을 자체 기호 테이블에 저장합니다. 즉, 다음 예에서는 세 개의 zval 변수 컨테이너

  <?php 
  $a = array(&#39;meaning&#39; => &#39;life&#39;, &#39;number&#39; => 42); 
   
  xdebug_debug_zval(&#39;a&#39;); 
  ?>
로그인 후 복사

를 생성합니다.
위 코드 출력:

  a: (refcount=1, is_ref=0)=array (&#39;meaning&#39; => (refcount=1, is_ref=0)=&#39;life&#39;, &#39;number&#39; => (refcount=1, is_ref=0)=42)
로그인 후 복사


3개의 zval 변수 컨테이너는 a, 의미, 숫자입니다. refcount를 늘리고 줄이는 규칙은 위에서 언급한 것과 동일합니다.


배열 자체를 배열로 추가하는 경우 요소:

  <?php 
  $a = array(&#39;one&#39;); 
   
  $a[] = &$a; 
   
  xdebug_debug_zval(&#39;a&#39;); 
  ?>
로그인 후 복사


위 코드의 결과 출력:

  a: (refcount=2, is_ref=1)=array (0 => (refcount=1, is_ref=0)=&#39;one&#39;, 1 => (refcount=2, is_ref=1)=...)
로그인 후 복사


可以看到数组a和数组本身元素a[1]指向的变量容器refcount为2

当对数组$a调用unset函数时,$a的refcount变为1,发生了内存泄漏

清理变量容器的问题尽管不再有某个作用域中的任何符号指向这个结构(就是变量容器),由于数组元素"1"仍然指向数组本身,所以这个容器不能被消除.因为没有另外的符号指向它,用户没有办法清除这个结构,结果就会导致内存泄漏.庆幸的是,php将在请求结束时清除这个数据结构,但是php清除前,将耗费不少内存空间


回收周期5.3.0PHP使用了新的同步周期回收算法,来处理上面所说的内存泄漏问题

首先,我们先要建立一些基本规则:
如果一个引用计数增加,它将继续被使用,当然就不再垃圾中.如果引用技术减少到零,所在的变量容器将被清除(free).就是说,仅仅在引用计数减少到非零值时,才会产生垃圾周期(grabage cycle).其次,在一个垃圾周期中,通过检查引用计数是否减1,并且检查哪些变量容器的引用次数是零,来发现哪部分是垃圾

2015810114143348.png (429×552)

为避免不得不检查所有引用计数可能减少的垃圾周期,这个算法把所有可能根(possible roots 都是zval变量容器),放在根缓冲区(root buffer)中(用紫色标记),这样可以同时确保每个可能的垃圾根(possible garbage root)在缓冲区只出现一次.仅仅在根缓冲区满了时,才对缓冲区内部所有不同的变量容器执行垃圾回收操作。

总结:以上就是本篇文的全部内容,希望能对大家的学习有所帮助。

相关推荐:

PHP实现基于SimpleXML生成和解析xml的方法

PHP实现基于XMLWriter操作xml的方法

PHP命名空间、性状与生成器案例详解

위 내용은 PHP 가비지 수집 메커니즘과 관련된 문제의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿