참조 카운팅(Reference Counting)

참조 카운팅(Reference Counting)

COM 인터페이스는 참조 카운팅으로 생명주기를 관리해요. 인터페이스가 변수에 할당될 때마다 카운트가 올라가고, 변수가 범위를 벗어나면 자동으로 내려가요. 카운트가 0이 되면 보통 그 인터페이스를 구현한 클래스 인스턴스가 해제돼요. 편리하지만, 컴파일러가 만드는 임시 변수 때문에 주의할 점이 있어요.

출처: Reference counting

본문

모든 COM 인터페이스는 참조 카운팅을 사용해요. 인터페이스가 변수에 할당될 때마다 그 참조 카운트가 갱신되고, 변수가 범위를 벗어나면 참조 카운트가 자동으로 감소해요. 참조 카운트가 0이 되면 보통 그 인터페이스를 구현하는 클래스의 인스턴스가 해제돼요.

이 메커니즘에는 주의가 필요해요. 컴파일러는 표현식을 평가할 때 임시 변수를 만들 수도 있고 만들지 않을 수도 있어요. 인터페이스를 임시 변수에 할당한 다음에야 실제 결과 변수에 할당할 수도 있죠. 임시 변수의 개수나 그것들이 정리되는 시점에 대해 어떤 가정도 하면 안 돼요. 이 부분은 다른 컴파일러(예: Delphi)가 인터페이스가 있는 표현식을 처리하는 방식과 다를 수 있고 실제로도 달라요.

예를 들어, 타입 캐스트도 하나의 표현식이에요.

Var
   B : AClass;

 begin
   // ...
   AInterface(B.Intf).testproc;
   // ...
 end;

인터페이스 intf가 참조 카운팅된다고 가정해 볼게요. 컴파일러가 B.Intf를 평가할 때 임시 변수를 만들어요. 이 변수는 프로시저가 끝날 때만 해제될 수 있어요. 따라서 예를 들어 프로시저가 끝나기 전에 인스턴스 B를 해제하는 것은 유효하지 않아요. 임시 변수가 정리될 때 B를 다시 해제하려 하기 때문이에요.

또, 함수 결과는 진입 시 non-nil인 유효한 COM 인터페이스를 가리킬 수 있어요. 그 이유는 함수 결과가 var 파라미터로 취급되기 때문이에요.

더 알아보기

  • 참조 카운팅이 가능한 이유인 IUnknown 기반 구조는 7.6 절(인터페이스와 COM)을 참고해요.
  • 인터페이스 정의와 기본 규칙은 7.1 절에서 확인할 수 있어요.
  • CORBA 인터페이스는 자동 참조 카운팅이 없다는 점은 7.7 절을 참고해요.