노트

레퍼런스 카운팅

Reference Counting

CS · 연결된 개념 3개

쉽게 말하면

레퍼런스 카운팅은 사무실에 처음 들어온 사람이 불을 켜고 마지막에 나가는 사람이 끄는 규칙이에요. 사람 수를 세 두면, 먼저 나간 사람 때문에 남은 사람이 어둠 속에 앉는 일이 없어요.

비유가 깨지는 곳 사무실은 들고 나는 게 분명하지만, 객체 둘이 서로를 가리키면 수가 0이 되지 않아 해제되지 않아요. 그래서 CPython은 순환을 찾는 별도 GC를 함께 써요.

공유 자원을 쓰는 사용자 수를 세어, 수가 0에서 1이 될 때 자원을 준비하고 1에서 0이 될 때 정리하는 기법. 사무실에 처음 들어온 사람이 불을 켜고, 마지막에 나가는 사람이 끄는 규칙과 같다.

let lockCount = 0
export function lockScroll() {
  if (lockCount++ === 0) document.body.style.overflow = 'hidden' // 0→1일 때만
}
export function unlockScroll() {
  if (--lockCount === 0) document.body.style.overflow = '' // 1→0일 때만
}

모달 위에 시트가 하나 더 열렸다 닫히는 경우를 생각해 보면 필요성이 보인다. 카운트 없이 "닫히면 스크롤 잠금 해제"로 짜면, 시트가 닫히는 순간 아직 열려 있는 모달 뒤에서 페이지가 스크롤된다. 카운트를 두면 마지막 하나가 닫힐 때만 풀린다. React Portal로 띄운 오버레이들이 겹칠 때 흔히 만나는 문제이고, 증감은 Effect의 설정·정리 함수에 짝지어 둔다(useEffect와 useLayoutEffect).

다른 곳에서의 쓰임

  • 메모리 관리: 파이썬(CPython)과 Swift는 객체를 가리키는 참조 수가 0이 되면 바로 해제한다. C++의 shared_ptr도 같다
  • 운영체제: 파일 핸들은 모든 프로세스가 닫아야 실제로 닫힌다
  • 한계: 서로를 가리키는 순환 참조(Reference Cycle)는 수가 0이 되지 않아 해제되지 않는다. 그래서 CPython은 순환을 찾는 별도 GC(Garbage Collector)를 함께 쓴다

증감이 짝을 이루지 않으면(정리 누락, 중복 해제) 바로 버그가 되므로, 획득과 해제를 한 함수나 한 Effect 안에 묶어 두는 것이 요령이다. 구독을 등록하고 해제하는 옵저버 패턴과 비슷한 주의가 필요하다.

연결된 개념

이 노트를 가리키는 문서

아직 없습니다.

뜻이 가까운 노트

  • 매개변수 객체 만들기

    여러 함수에 늘 함께 넘겨지는 값 묶음(데이터 뭉치, Data Clumps)을 하나의 객체로 묶어 넘기는 리팩터링.

  • React Compiler

    React Compiler는 빌드 타임에 컴포넌트와 훅을 분석해 메모이제이션(Memoization) 코드를 자동으로 넣어 주는 컴파일러다. 개발자가 손으로 붙이던 useMemo·useCallback·memo를 대신한다. 2025년 10월 1.0이 나왔다.

  • 운영 Node 프로세스의 메모리 누수 찾기

    살아 있는 Node 서버에 inspector를 붙이고, 힙 스냅샷 두 장을 비교해 무엇이 쌓이는지, retainer로 누가 붙잡고 있는지 찾는 절차.

  • 변수·컬렉션 캡슐화

    넓은 범위에서 쓰이는 데이터에 직접 접근하지 못하게 하고, 읽고 쓰는 함수를 통해서만 다루게 하는 리팩터링. 데이터를 옮기거나 바꿀 때 고쳐야 할 곳이 접근 함수 한 곳으로 좁아진다.

  • 서버 렌더에서 훅이 하는 일

    서버 렌더(Server-Side Rendering, SSR)에서도 컴포넌트 함수는 실제로 호출되고, 그 안의 훅도 호출은 된다. 다만 서버에는 커밋(DOM 반영)이 없어서, 렌더 중 동기적으로 값을 계산하는 훅만 일하고 커밋 뒤에 도는 훅은 아무것도 하지 않는다. "이 훅은 클라이언트에서만 동작한다"는 말은 대개 "Effect 안의 일은 클라이언트에서만 일어난다"는 뜻이다.

보기 옵션