관리 메뉴

기억을 위한 기록들

가비지 컬렉션/참조 카운팅에 관하여 본문

C & CPP/Smart Pointer

가비지 컬렉션/참조 카운팅에 관하여

에드윈H 2021. 2. 18. 21:46

가비지 컬렉터는?

- 메모리 누수를 막으려는 시도를 해준다.
- 주기적으로 컬렉션을 실행.
- 충분한 여유 메모리가 없을 때 컬렉션이 실행됨 (스케쥴에 따라 또는 수동으로도 실행가능)
- 매 주기마다,GC는 루트("root")를 확인함
   1. 전역변수
   2. 스택
   3. 레지스터
- 힙에 있는 개체에 루트를 통해 접근할 수 있는지 판단
- 접근할 수 없다면, 가비지로 간주해서 해제

 

 

문제점?

- 사용되지 않는 메모리를 즉시 정리하지 않음.

- GC가 메모리를 해제해야 하는지 판단하는 동안 애플리케이션이 멈추거나 버벅일 수 있음.

 

 

 

 

참조 카운팅?

- 가비지컬렉션처럼, 개체에 대한 참조가 없을 때 개체가 해제됨.
- 언제든 참조 횟수를 활용해서 특정 개체가 몇 번이나 참조되고 있는지 판단 가능
- 어떤 개체 A를 다른 개체 B가 참조할 때 횟수가 늘어남
- B가 참조를 그만둘 때 횟수 줄어듦 (ex B가 범위(scope)를 벗어나는 경우)

 

 

수동참조카운팅/자동참조카운팅 뭐가 더 나을지에 대한 정답은 없다.

 

 

강한 참조란

- 한 개체가 다른 개체를 참조할때 다른개체는 절대 소멸되지 않음을 의미.

- 강한 참조의 수를 저장하기 위해 강한 참조 카운트를 사용

- 일반적으로 새 인스턴스, 즉 개체에 대한 참조를 만들 때 강한 참조 횟수가 늘어남.

- 강한 참조 횟수가 0이 될 때 해당 개체는 소멸.

 

 

참조 카운팅의 문제점

1. 참조 횟수는 너무 자주 바뀜
 - 멀티 쓰레드 환경에서 안전하려면 , lockj이나 원자적(automic)연산이 필요
 - ++mRefCount보다 확연히 느림.
2. 순환(circular) 참조
 - 개체 A가 개체 B를 참조.
 - 개체 B가 개체 A를 참조.
 - 절대 해제되지 않음.

 

가비지 컬렉션 vs 참조 카운팅

가비지컬렉션
- 사용하기 확실히 더 쉬움
- 실시간 또는 고성능 프로그램에 적합하지 않음.
참조 카운팅
- 여전히 사용하기 쉬움
- 실시간 또는 고성능 프로그램에 적합
- 멀티 스레드 환경에서는 순수한 포인터보다 훨씬 느림.