Bin's Blog

Garbage collection 본문

JavaScript

Garbage collection

hotIce 2023. 9. 18. 12:52
728x90

글의 시작

오늘 다루는 주제는 내가 코어 자바스크립트를 공부하고, 또 강의를 챙겨보면서 평소해 궁금했던 내용이다. 

면접 때도 단골 질문으로 등장한다. 자바스크립트는 눈에 보이지 않는 곳에서 메모리 관리를 수행한다.

내가 궁금했던 부분은 "왜 자바스크립트가 쓰레기 수집을 하지?",  "왜 쓰레기를 수집해야 하는지?"

이런 행동이 어떤 목적과 의미를 지니는지 이번 포스팅을 통해서 파헤쳐 보자. 

 

Garbage란?

Garbage는 컴퓨터의 메모리에 있지만 앞으로 사용되지 않을 데이터나 객체 또는 메모리 영역을 가리킨다. 모든 컴퓨터 시스템은 제한적인 메모리를 가지고 있고, 대부분의 소프트웨어 garbage를 만들어내기 때문에, 이를 메모리에서 해제하여 다시 사용할 수 있게 해야 한다. 

 

간단한 예시

// user엔 객체 참조 값이 저장된다.
let user = {
  name: "Kevin"
};

 

이 그림에서 화살표는 객체 참조를 나타낸다. 전역 변수 "user"는 {name : "Kevin"} 이라는 객체를 참조한다. Kevin의 프로퍼티 "name"은 원시값을 저장하고 있기 때문에 객체 안에 표현했다.

 

user의 값을 다른 값으로 덮어쓰면 참조(화살표)가 사라진다.

user = null;

이제 Kevin은 도달할 수 없는 상태가 되었다. Kevin에 접근할 방법도, Kevin을 참조하는 것도 모두 사라졌다. Garbage collector는 이제 Kevin에 저장된 데이터를 삭제하고, Kevin을 메모리에서 삭제한다. 

 

Garbage Collection이란?

가비지컬렉션(Garbage collection, GC)은 자동으로 메모리를 관리해주는 기법이다.

프로세스에 의해 할당되었지만, 더이상 참조되지 않는 메모리를 garbage라고 하고, 이러한 garbage를 수거하는 작업은 Garbage collection이 진행한다.

 

 

내부 알고리즘

순환 참조의 경우 Garbage collection의 대상에서 제외되어서, 메모리 누수 문제가 발생하는데 그 문제를 해결할 수 있는

Garbage collection의 기본 알고리즘인 Mark-and-Sweep에 대해서 알아보자. 

 

Mark-and-Sweep

장점

- 비교적 알고리즘이 단순

 

단점

- 메모리 파편화 문제(Fregemantation)

- Memory Corruption을 방지하기 위해 Heap 사용을 제한해서 Suspend 현상이 생긴다. 

 

Mark-and-Sweep은 두 phase로 진행된다. 

 

먼저 Mark phase에서는 모든 object들의 header의 mark bit를 false로 만든다. 

 

 

object들의 참조 상황

 

root object는 현재 바로 접근 가능한 object들로 구성된다. 

- 현재 스코프의 local 변수

- 전역 변수

 

root object로부터 접근 가능한 모든 object들의 mark bit를 true로 바꾼다. 

 

참조 가능한 object들을 mark

 

이후 Sweep phase가 시작되어 mark 되어있지 않은 object들을 모두 쓸어(sweep)버린다.

mark 되지 않은 object들을 sweep

이로써 순환 참조되어 있던 두 object가 간단히 제거 되었다.

 

Mark-and-Sweep은 단점으로 인해 그대로 사용하지 않고, 개선된 알고리즘으로 GC로 진행한다. 

 

자바스크립트 엔진은 실행에 영향을 미치지 않으면서 가비지 컬렉션을 더 빠르게 하는 다양한 최적화 기법을 적용한다. 

 

최적화 기법

1️⃣ generational collection(세대별 수집) : 객체를 '새로운 객체'와 '오래된 객체'로 나눈다. 객체 상당수는 생성 이후 제 역할을 빠르게 수행해 금방 쓸모가 없어지는데, 이런 객체를 '새로운 객체'로 구분한다. Garbage Collector는 이런 객체를 공격적으로 메모리에서 제거한다. 일정 시간 이상 동안 살아남은 객체는 "오래된 객체"로 구분하고, 가비지 컬렉터가 덜 감시한다. 

 

2️⃣ incremental collection(점진적 수집) : 방문해야 할 객체가 많다면 모든 객체를 한 번에 방문하고 mark하는데 상당한 시간이 걸린다. Garbage collection에 많은 자원이 사용되어 실행 속도가 눈에 띄게 느려진다. 자바스크립트 엔진은 이러한 문제를 개선하기 위해 Garbage collection을 여러 부분으로 분리한 다음, 각 부분을 별도로 수행한다. 작업을 분리하고, 변경 사항을 추적하는 데 추가 작업이 필요하긴 하지만, 긴 지연을 짧은 지연 여러 개로 분산시킬 수 있다는 장점이 있다.  

 

3️⃣ idle-time collection(유휴 시간 수집) - Garbage collector는 실행에 주는 영향을 최소화하기 위해 CPU가 유휴(사용되지 않는 상태)일 때에만 Garbage collection을 실행한다. 

 

 

글의 마무리

인간은 사용하지 않는 물건은 쓰레기통이나 재활용품에 버린다. 이런 활동을 통해서 주어진 주거 환경을 더 쾌척하고 공간을 확보한다. 그렇지 않으면 엉망진창이 될 것이다. 컴퓨터의 자원들도 역시 한정적인 자원 안에서 극한의 효율을 추구하게 설계되어 있어서, 쓰지 않는 것들을 정리해줄 필요가 있다. 

자바스크립트는 감사하게도 우리가 보이지 않는 공간에서 열심히 일을 처리하는 든든한 일꾼이다. 우리가 이렇게 언어를 더 쉽고 편하게 쓸 수 있는 것은 많은 개발자의 끊임없는 고민과 철학이 있었기 때문이라고 생각한다.   

 

📚 참고

https://ko.javascript.info/garbage-collection

728x90

'JavaScript' 카테고리의 다른 글

기본형 데이터와 참조형 데이터  (0) 2023.10.24
JS Framework & Library 트렌드  (0) 2023.10.14
this Keyword  (0) 2023.08.30
번들링이란?  (0) 2023.08.26
npm vs yarn  (0) 2023.08.05