php 메모리 관리 메커니즘 과 쓰레기 회수 메커니즘

1.메모리 관리 메커니즘
코드 먼저 보기:

<?php
//      
var_dump(memory_get_usage());//      ,  true      ,         
$a = "laruence";
var_dump(memory_get_usage());
unset($a);
var_dump(memory_get_usage());
//  (        ,        ,PHP  ,          ):
//int 240552
//int 240720
//int 240552
변 수 를 정의 한 후에 메모리 가 증가 하고 변 수 를 제거 한 후에 메모리 회복(예전 과 같 지 않 을 수도 있 습 니 다).변 수 를 정의 할 때 메모리 신청 을 한 것 같 습 니 다.사실은 그렇지 않 습 니 다.phop 은 미리 메모리 신청 을 합 니 다.변 수 를 정의 할 때마다 메모리 신청 을 하지 않 습 니 다.
우선,우 리 는 하나의 사 고 를 깨 뜨 려 야 한다.PHP 는 C 언어 처럼 메모리 할당 과 관련 된 API 를 호출 해 야 메모리 배분 이 가능 하 다.즉,PHP 에 서 는 우리 가 볼 수 없 는 메모리 배분 과정 이 많다 는 것 이다.
예 를 들 어:
$a = "laruence";
암시 적 메모리 할당 점 은 다음 과 같 습 니 다.
  • 변수 이름 으로 메모 리 를 분배 하고 기호 표 에 저장 합 니 다
  • 변수 값 할당 메모리
    그래서 표상 만 볼 수 는 없다.
    둘째,의심 하지 마 세 요.PHP 의 unset 는 확실히 메모 리 를 방출 할 것 입 니 다.그러나 이 방출 은 C 프로 그래 밍 의 의미 에서 방출 되 는 것 이 아니 라 OS 에 전달 되 는 것 이 아 닙 니 다.
    PHP 에 있어 서,C 언어 와 메모리 분배 가 비슷 한 메모리 관리 API 를 제공 합 니 다.
    
    emalloc(size_t size);
    efree(void *ptr);
    ecalloc(size_t nmemb, size_t size);
    erealloc(void *ptr, size_t size);
    estrdup(const char *s);
    estrndup(const char *s, unsigned int length);
    이 API 와 C 의 API 의 미 는 대응 되 며,PHP 내부 에 서 는 이 API 를 통 해 메모 리 를 관리 합 니 다.
    우리 가 emalloc 를 호출 하여 메모 리 를 신청 할 때 PHP 는 단순히 OS 에 메모 리 를 요구 하 는 것 이 아니 라 OS 처럼 큰 메모 리 를 요구 한 다음 에 그 중의 하 나 를 신청자 에 게 분배 합 니 다.그러면 논리 적 으로 메모 리 를 신청 할 때 OS 에 메모 리 를 신청 하지 않 아 도 되 고 빈번 한 시스템 호출 을 피 할 수 있 습 니 다.
    예 를 들 어 다음 과 같은 예:
    
    var_dump(memory_get_usage(true));//      real_size
    $a = "laruence";
    var_dump(memory_get_usage(true));
    unset($a);
    var_dump(memory_get_usage(true));
    //  
    //int 262144
    //int 262144
    //int 262144
    즉,우리 가 변수$a 를 정의 할 때,PHP 는 시스템 에 새 메모 리 를 신청 하지 않 았 습 니 다.마찬가지 로,우리 가 efree 를 호출 하여 메모 리 를 방출 할 때,PHP 는 메모 리 를 OS 에 돌려 주지 않 고,이 메모 리 를 자신 이 유지 하 는 남 은 메모리 목록 에 넣 습 니 다.작은 블록 내 저장 에 있어 서,더 가능 한 것 은 메모리 캐 시 목록 에 넣 는 것 입 니 다.
    
    $a = "hello";
    //     ,      :
    //1.   ,      
    //2.          
    //3.        ,            ,              (    )
    늘 기만 하고 줄 지 않 는 수조
    Hashtable 은 PHP 의 핵심 구조 이 고 배열 도 그녀 로 표시 하 며 기호 표 도 관련 배열 입 니 다.다음 코드 에 대해 서 는:
    
    var_dump(memory_get_usage());
    for($i=0;$i<100;$i++)
    {
        $a = "test".$i;
        $$a = "hello";
    }
    var_dump(memory_get_usage());
    for($i=0;$i<100;$i++)
    {
        $a = "test".$i;
        unset($$a);
    }
    var_dump(memory_get_usage());
    우 리 는 100 개의 변 수 를 정의 한 후에 Unset 을 누 르 면 출력 을 볼 수 있 습 니 다.
    //int 242104
    //int 259768
    //int 242920
    왜 이렇게 많은 메모리 가 부족 합 니까?
    이것 은 Hashtable 에 대해 정의 할 때 알 수 없 는 개수 의 요 소 를 저장 하기 위해 충분 한 메모리 블록 을 한꺼번에 분배 할 수 없 기 때문에 PHP 는 초기 화 할 때 일부 메모리 블록 만 HashTable 에 분배 하고 부족 할 때 RESIZE 를 확대 합 니 다.Hashtable 은 확장 만 할 수 있 고 줄 어 들 지 않 습 니 다.
    위의 예 에 대해 우리 가 100 개의 변 수 를 저장 할 때 기호 표 는 사용 하기에 부족 하고 확장 을 했 습 니 다.그러나 우리 가 이 100 개의 변 수 를 차례대로 unset 에서 떨 어 뜨 린 후에 변수 가 차지 하 는 메모리(118848 C 104448)는 방출 되 었 지만 기호 표 는 축소 되 지 않 았 기 때문에 이런 적은 메모리 들 은 기호 표 자체 에 의 해 차지 되 었 습 니 다.
    2.쓰레기 회수 메커니즘
    PHP 변 수 는 zval 용기 에 저 장 됩 니 다.
    1.변수 종류
    2.변수 값
    3. is_ref 는 주소 참조 가 있 는 지 여부 입 니 다.
    4.refcount 가 이 값 을 가리 키 는 변수 수
    변수 할당 시:isref 는 false 이 고 refcount 는 1 입 니 다.
    
    $a = 1;
    xdebug_debug_zval('a');
    echo PHP_EOL;//   ,             
    출력:
    a:
    변수 a 의 값 을 변수 b 에 부여 합 니 다.변수 b 는 메모리 에 값 을 저장 하지 않 고 변수 a 의 값 을 가리 키 며 변수 a 가 동작 할 때 까지 합 니 다.
    
    $b = $a;
    xdebug_debug_zval('a');
    echo PHP_EOL;
    출력:
    
    a:
    
    (refcount=2, is_ref=0),
    int
    
     1
    
    $c = &$a;
    xdebug_debug_zval('a');
    echo PHP_EOL;
    
    xdebug_debug_zval('b');
    echo PHP_EOL;
    출력:
    
    a:
    
    (refcount=2, is_ref=1),
    int
    
     1
    b:
    
    (refcount=1, is_ref=0),
    int
    
     1
    프로그램 이 변수 a 를 다시 작 동 하기 때문에 변수 b 는 스스로 메모리 에 값 을 넣 으 라 고 신청 합 니 다.
    따라서 변수 a 의 zval 용기 에서 refcount 는 1 을 1 로 줄 이 고 변수 c 는 a 를 가리 키 기 때문에 refcount 는 1 을 추가 하여 2,is 로 변 합 니 다.ref 에서 true 로 변경
    쓰레기 수 거
    1.5.2 버 전이 나 이전 버 전에 서 PHP 는 refcount 값 에 따라 쓰레기 인지 아 닌 지 를 판단 합 니 다.
    refcount 값 이 0 이면 PHP 는 쓰레기 로 방출 됩 니 다.
    이러한 회수 메커니즘 은 결함 이 있어 서 링 모양 참조 변 수 를 회수 할 수 없습니다.
    링 참조:
    
    $attr = array("hello");
    $attr[]= &$attr;
    
    xdebug_debug_zval('attr');
    echo PHP_EOL;
    출력:
    
    attr:
    
    (refcount=2, is_ref=1),
    array (size=2)
      0 => (refcount=1, is_ref=0),
    string
    
     'hello' (length=5)
      1 => (refcount=2, is_ref=1),
        &array
    2.5.3 이후 버 전 은 쓰레기 회수 체 제 를 개선 했다.
    zval 용기 에 refcount 가 증가 하 는 것 을 발견 하면 쓰레기 가 아니 라 는 뜻 입 니 다.
    zval 용기 에 있 는 refcount 가 감소 하고 있 는 것 을 발견 하면 0 으로 줄 이면 쓰레기 로 회수 합 니 다.
    zval 용기 에 있 는 refcount 가 줄 어 들 고 0 으로 줄 어 들 지 않 은 것 을 발견 하면 PHP 는 이 값 을 버퍼 에 넣 어 쓰레기 의 의심 대상 으로 삼 습 니 다.
    버퍼 가 임계값 에 도달 하면 PHP 는 모든 값 을 옮 겨 다 니 는 방법 을 자동 으로 호출 합 니 다.쓰레기 가 발견 되면 청소 합 니 다.
    이상 은 phop 메모리 관리 체제 와 쓰레기 회수 체제 에 대한 상세 한 내용 입 니 다.phop 메모리 관리 체제 와 쓰레기 회수 체제 에 관 한 자 료 는 우리 의 다른 관련 글 에 관심 을 가 져 주 십시오!

    좋은 웹페이지 즐겨찾기