프로그래밍 언어라고 해서 모두 Garbage collection 메커니즘이 존재하는 건 아니다. C나 C++처럼 직접 malloc이나 free 함수를 통해 개발자가 직접 메모리를 관리해야 하는 경우도 있다. 반면 자바스크립트, 파이썬, 자바 등등의 경우 GC 메커니즘이 존재한다. 그 중에서도 자바스크립트의 경우 브라우저 별로 자바스크립트 엔진이 자체적으로 최적화된 GC 메커니즘을 제공한다. 이 점이 흥미로워서 chrome의 자바스크립트 엔진인 v8의 docs를 좀 더 파보았고, 내용이 많아서 이참에 아예 GC 시리즈로 포스팅을 할 예정이다.

FinalizationRegistry

이번에 알게되었는데 자바스크립트에 GC를 감지할 수 있는 API가 있었다. FinalizationRegistry라는 생성자 함수로 객체를 하나 만들면서 인자로 콜백을 전달한 후, 특정 변수를 register해놓으면 GC가 되었을 때 인자로 전달했던 콜백이 실행되는 구조이다. 이 때 콜백으로 전달하는 콜백을 clean up 콜백이라고 부른다.

참고: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry

브라우저에서도 바로 확인할 수 있다.

register 메서드에

(1)등록할 변수와
(2)클린업 콜백에 전달할 인자를

인자로 전달하는 것이다.

시간을 두고 기다리면 알아서 GC가 되지만,
성격이 급한 나 ^^;;


개발자도구의 Memory 탭에서 휴지통 버튼을 누르면 GC를 강제할 수도 있다.

이렇게 GC가 강제되어 클린업 콜백에 전달한 메시지가 console 출력되는 것을 확인할 수 있다.

그렇다면 클로저의 경우는 어떨까?

클로저를 사용할 경우 외부함수의 지역변수는 GC되지 않을까?

클로저가 무엇인지?

function outer() {
  const x = 1;
  
  function inner() {
    console.log(x, 'outer의 렉시컬 환경은 살아있다!');
  }
  
  return inner;
}

// inner를 return해서 inner 변수에 할당 후 호출
const inner = outer()
inner();
// 1 'outer의 렉시컬 환경은 살아있다!'

[전제]

(1) 외부함수 내부에 중첩된 내부함수가 상위 스코프인 외부 함수의 지역변수를 참조하고 있을 때
(2) 외부함수가 내부함수를 return하고

[상황]

(1) 외부함수의 실행 컨텍스트 스택이 pop되더라도
(2) 여전히 종료된 외부함수의 지역변수를 내부 함수에서 참조할 수 있다.
(3) 이때의 내부 함수를 클로저라고 부른다.
(4) 외부함수는 이미 죽었지만(?) 지역변수는 참조되고 있고 외부 함수의 렉시컬 환경도 전역에서 참조되고 있다.

[결과]

(1) 내부함수에 의해 참조되고 있는 외부함수의 지역 변수는 GC 대상이 아니다.

closure의 x가 GC의 수거 대상이 정말 아닌지 FinalizationRegistry를 이용해 눈으로 확인해보자.

memory 탭의 휴지통 버튼을 아무리 눌러봐도 x는 수거되지 않는다.

전역 객체의 key가 되었을 때는 GC되지 않을까?

역시 수거되지 않는다.

이는 전역 객체가 여전히 x 변수를 참조하고 있기 때문에 수거 대상이 아니기 때문이다.

GC를 눈으로 확인할 수 있는 생성자 함수인 FinalizationRegistry.. 크게 쓸데는 없을 것 같지만 흥미로워서 시리즈의 첫번째 포스팅 주제로 잡아봤다.

다음 포스팅에서는 minor GC와 major GC를 비교해서 설명해보려고 한다. 객체의 나이별로 공간을 분류하는 잔인한 그곳의 세계를 파헤쳐보자.

참고:
Experiments with the JavaScript Garbage Collector
https://dev.to/codux/experiments-with-the-javascript-garbage-collector-2ae3

MDN
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry

profile
기록에 진심인 개발자 🌿

0개의 댓글

관련 채용 정보

Powered by GraphCDN, the GraphQL CDN