순환 가비지 수집 지원
*********************

순환 참조를 포함하는 가비지를 탐지하고 수집하는 파이썬의 지원은 역시
컨테이너일 수 있는 다른 객체의 "컨테이너" 인 객체 형의 지원이 필요합니
다. 다른 객체에 대한 참조를 저장하지 않거나, 원자 형(가령 숫자나 문자
열)에 대한 참조만 저장하는 형은 가비지 수집에 대한 어떤 명시적인 지원
을 제공할 필요가 없습니다.

컨테이너형을 만들려면, 형 객체의 "tp_flags" 필드가
"Py_TPFLAGS_HAVE_GC"를 포함해야 하고 "tp_traverse" 처리기 구현을 제공
해야 합니다. 형의 인스턴스가 가변이면, "tp_clear" 구현도 제공해야 합니
다.

Py_TPFLAGS_HAVE_GC

   이 플래그가 설정된 형의 객체는 여기에 설명된 규칙을 준수해야 합니다
   . 편의를 위해 이러한 객체를 컨테이너 객체라고 하겠습니다.

컨테이너형의 생성자는 두 가지 규칙을 준수해야 합니다:

1. 객체의 메모리는 "PyObject_GC_New()" 나 "PyObject_GC_NewVar()"를 사
   용하여 할당해야 합니다.

2. 다른 컨테이너에 대한 참조를 포함할 수 있는 모든 필드가 초기화되면,
   "PyObject_GC_Track()"를 호출해야 합니다.

TYPE* PyObject_GC_New(TYPE, PyTypeObject *type)

   "PyObject_New()"와 유사하지만, "Py_TPFLAGS_HAVE_GC" 플래그가 설정된
   컨테이너 객체를 위한 것.

TYPE* PyObject_GC_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size)

   "PyObject_NewVar()"와 유사하지만, "Py_TPFLAGS_HAVE_GC" 플래그가 설
   정된 컨테이너 객체를 위한 것.

TYPE* PyObject_GC_Resize(TYPE, PyVarObject *op, Py_ssize_t newsize)

   Resize an object allocated by "PyObject_NewVar()".  Returns the
   resized object or "NULL" on failure.  *op* must not be tracked by
   the collector yet.

void PyObject_GC_Track(PyObject *op)

   수집기가 추적하는 컨테이너 객체 집합에 객체 *op*를 추가합니다. 수집
   기는 예기치 않은 시간에 실행될 수 있으므로 추적되는 동안 객체가 유
   효해야 합니다. "tp_traverse" 처리기가 탐색하는 모든 필드가 유효해지
   면 호출해야 합니다, 보통 생성자의 끝부분 근처입니다.

void _PyObject_GC_TRACK(PyObject *op)

   "PyObject_GC_Track()"의 매크로 버전. 확장 모듈에는 사용하지 말아야
   합니다.

   버전 3.6부터 폐지: 이 매크로는 파이썬 3.8에서 삭제되었습니다.

마찬가지로, 객체의 할당해제자(deallocator)는 비슷한 규칙 쌍을 준수해야
합니다:

1. 다른 컨테이너를 참조하는 필드가 무효화 되기 전에,
   "PyObject_GC_UnTrack()"를 호출해야 합니다.

2. 객체의 메모리는 "PyObject_GC_Del()"를 사용하여 할당 해제되어야 합니
   다.

void PyObject_GC_Del(void *op)

   "PyObject_GC_New()" 나 "PyObject_GC_NewVar()"를 사용하여 객체에 할
   당된 메모리를 해제합니다.

void PyObject_GC_UnTrack(void *op)

   수집기가 추적하는 컨테이너 객체 집합에서 *op* 객체를 제거합니다.
   "PyObject_GC_Track()"를 이 객체에 대해 다시 호출하여 추적 객체 집합
   에 다시 추가할 수 있음에 유의하십시오. 할당해제자("tp_dealloc" 처리
   기)는 "tp_traverse" 처리기에서 사용하는 필드가 무효화 되기 전에 객
   체에 대해 이 함수를 호출해야 합니다.

void _PyObject_GC_UNTRACK(PyObject *op)

   "PyObject_GC_UnTrack()"의 매크로 버전. 확장 모듈에는 사용하지 말아
   야 합니다.

   버전 3.6부터 폐지: 이 매크로는 파이썬 3.8에서 삭제되었습니다.

"tp_traverse" 처리기는 다음과 같은 형의 함수 매개 변수를 받아들입니다:

int (*visitproc)(PyObject *object, void *arg)

   "tp_traverse" 처리기에 전달되는 방문자 함수의 형. 이 함수는 탐색하
   는 객체를 *object*로, "tp_traverse" 처리기의 세 번째 매개 변수를
   *arg*로 호출되어야 합니다. 파이썬 코어는 순환 가비지 탐지를 구현하
   기 위해 여러 방문자 함수를 사용합니다; 사용자가 자신의 방문자 함수
   를 작성해야 할 필요는 없습니다.

"tp_traverse" 처리기는 다음 형이어야 합니다:

int (*traverseproc)(PyObject *self, visitproc visit, void *arg)

   Traversal function for a container object.  Implementations must
   call the *visit* function for each object directly contained by
   *self*, with the parameters to *visit* being the contained object
   and the *arg* value passed to the handler.  The *visit* function
   must not be called with a "NULL" object argument.  If *visit*
   returns a non-zero value that value should be returned immediately.

"tp_traverse" 처리기 작성을 단순화하기 위해, "Py_VISIT()" 매크로가 제
공됩니다. 이 매크로를 사용하려면, "tp_traverse" 구현은 인자의 이름을
정확히 *visit* 와 *arg*로 지정해야 합니다:

void Py_VISIT(PyObject *o)

   If *o* is not "NULL", call the *visit* callback, with arguments *o*
   and *arg*.  If *visit* returns a non-zero value, then return it.
   Using this macro, "tp_traverse" handlers look like:

      static int
      my_traverse(Noddy *self, visitproc visit, void *arg)
      {
          Py_VISIT(self->foo);
          Py_VISIT(self->bar);
          return 0;
      }

The "tp_clear" handler must be of the "inquiry" type, or "NULL" if the
object is immutable.

int (*inquiry)(PyObject *self)

   참조 순환을 생성했을 수 있는 참조를 삭제합니다. 불변 객체는 참조 순
   환을 직접 생성할 수 없으므로, 이 메서드를 정의 할 필요가 없습니다.
   이 메서드를 호출한 후에도 객체가 유효해야 합니다 (단지 참조에 대해
   "Py_DECREF()"를 호출하지 마십시오). 이 객체가 참조 순환에 참여하고
   있음을 수집기가 감지하면 이 메서드를 호출합니다.
