python 쓰레기 수집 메커니즘 의 실례 상세 설명

python 쓰레기 수집 메커니즘 의 실례 상세 설명
python 쓰레기 수집 에 관 한 내용 을 자세히 말 하려 면 아직도 매우 많 습 니 다.여 기 는 대략적인 요약 일 뿐 입 니 다.
Python 의 가장 주요 한 부분 과 절대 다수의 경우 인용 계 수 를 사용 합 니 다.모든 PyObject 정 의 는 다음 과 같 습 니 다.

#define PyObject_HEAD          \ 
  Py_ssize_t ob_refcnt;        \ 
  struct _typeobject *ob_type; 
typedef struct _object { 
  PyObject_HEAD 
} PyObject; 
모든 pyobject 는 refcnt 가 자신의 인용 수 를 기록 하고 인용 수가 0 이면 회수 합 니 다.
인용 계수 의 장점 은 실시 간성 이다.다른 대상 이 인용 하지 않 으 면 바로 회수 할 수 있어 보기 좋다.그런데 왜 많은 언어 가 이 방안 을 채택 하지 않 는 지,인용 계수 에 치 명 적 인 단점 이 있어 순환 인용 문 제 를 해결 할 수 없다.예 를 들 어:

a = [] 
b = [] 
a.append(b) 
b.append(a) 
사실은 다른 변수 가 a,b 를 인용 하지 않 았 다.그러면 그들 은 실제로 회수 되 어야 하지만 서로 인용 하 는 관계 로 인해 그들의 인용 수 는 모두 1 이 고 회수 할 수 없다.
python 에서 서로 인용 하 는 문 제 는 list,dictionary,class,instance 와 같은 용기 에 만 존재 합 니 다.이 문 제 를 해결 하기 위해 python 은 표 시―제거 와 세대 구분―다른 두 가지 체 제 를 도입 했다.
사실 python 의 용 기 는 이전에 말 한 것 처럼 그렇게 간단 하지 않 습 니 다.pyobjecthead 전에 PyGC 가 하나 더 있 습 니 다.헤드,즉 용기 의 순환 인용 문 제 를 처리 하 는 데 쓰 인 다.

typedef union _gc_head { 
  struct { 
    union _gc_head *gc_next; 
    union _gc_head *gc_prev; 
    Py_ssize_t gc_refs; 
  } gc; 
  long double dummy; /* force worst-case alignment */ 
} PyGC_Head; 
모든 생 성 된 용기 류 의 대상 은 수집 가능 한 대상 링크 에 기 록 됩 니 다.위의 구 조 를 통 해 우 리 는 사실은 양 방향 링크 를 구축 한 것 임 을 알 수 있 습 니 다.그러면 우 리 는 순환 참조 가 발생 할 수 있 는 모든 상황 을 추적 할 수 있 습 니 다.int,string 등 간단 한 것 은 용기 유형 이 아니 라 인용 기술 이 0 이면 회수 된다.그러나 잦 은 malloc 와 free 는 효율 에 심각 한 영향 을 미 치기 때문에 python 은 대량의 대상 풀 을 사용 하여 효율 을 높 였 다.
태그-제거 에는 쓰레기 회수 의 두 가지 측면 이 포함 되 어 있 습 니 다.(1)회수 할 수 있 는 대상 을 찾 습 니 다.(2)회수 대상 을 찾 습 니 다.python 의 표 시 는 루트 object 부터 모든 용기 류 대상 을 옮 겨 다 니 며 인용 을 통 해 도착 할 수 있 는 대상 을 찾 아 reachable 이 유지 하 는 링크 에 넣 습 니 다.도착 할 수 없 는 것 은 unbreachable 유지 하 는 링크 에 넣 습 니 다.이 과정 이 끝 난 후 unreachable 에 있 는 요 소 를 회수 하면 됩 니 다.
그렇다면 이전 순환 인용 상황 에 어떻게 대응 할 것 인가?python 에 유효한 인용 수가 생 길 수 있 습 니 다.gc.gc 가 존재 합 니 다.refs 에 서 는 위의 a,b 와 같은 실제 인용 수 는 1 이지 만 효과 적 인 인용 수 는 0(순환 중의 인용 수 는 모두 1 감소)입 니 다.pyobject 안의 refcnt 를 직접 바 꿀 수 없 기 때문에 일련의 문제 가 발생 할 수 있 습 니 다.우 리 는 효과 적 인 인용 수 를 gc.gc 에 기록 할 수 있 습 니 다.refs 에 서 는 a,b 의 실제 유효 인용 수가 0 이기 때문에 회수 할 수 있 습 니 다.
다음은 다른 상황 이다.

a = [] 
b = [] 
c = a 
a.append(b) 
b.append(a) 
여기 ab 도 순환 인용 이지 만 c 가 많 으 면 a 를 인용 합 니 다.순환 중의 유효 인용 수 를 계산 하면 a 의 인용 수 는 1 이 고 b 의 인용 수 는 0 입 니 다.b 는 회수 되 어야 할 것 같 지만 실제로 a 는 회수 되 지 않 고 a 는 b 를 인용 하기 때문에 b 도 reachable 링크 에 넣 어 회수 되 지 않 습 니 다.gc.gcrefs 는 1 로 설 치 됩 니 다.
또 다른 세대 별로 회수 하 는 것 은 메모리 에 있 는 대상 이 빈번 한 malloc 와 free 를 말 하 는 것 이다.어떤 대상 은 비교적 오래 간다.만약 에 한 대상 이 여러 번 쓰레기 를 수집 하고 제거 한 후에 도 존재 한다 면 우 리 는 이 대상 이 장시간 유용 하 다 고 생각 할 수 있 고 자주 검 사 를 하지 않 아 도 된다.python 은 3 세대 로 나 뉘 는데 각각 3 개의 링크 유지보수 이 고 0 대 는 최대 700 개의 대상 을 유지 하 며 1 세대 10 개,2 세대 10 개 를 유지 합 니 다.대상 이 이 수 를 초과 하면 태그-제거 알고리즘 을 호출 하여 회수 합 니 다.0 대 대상 은 시간 이 지나 면 1 세대 2 세대 로 이동 한 뒤 이들 에 대한 검 측 회수 가 0 대 에 비해 그리 잦 지 않 을 것 으로 예상 된다.
주의해 야 할 것 은 python 의 주요 메커니즘 은 인용 기술,표기-제거 와 세대 별 수집 은 인용 계수 의 단점 을 보완 하기 위해 추 가 된 것 이다.즉,후 두 가 지 는 기본적으로 용기 류 의 순환 인용 에서 만 역할 을 발휘 할 수 있다 는 것 이다.
이상 은 python 쓰레기 수집 체제 의 사례 상세 한 설명 입 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남기 거나 본 사이트 지역사회 에 가서 토론 을 하 십시오.읽 어 주 셔 서 감사합니다. 여러분 께 도움 이 되 기 를 바 랍 니 다.본 사이트 에 대한 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기