Language/JS & TS

[JS] 가비지 컬렉션(Garbage Collection)

bill's tech log 2024. 5. 1. 14:22

 현재 회사에 주 백엔드가 node로 되어있기 때문에, 자바스크립트, 타입스크립트에 대한 기본적이지만 핵심적인 내용들을 다뤄볼까 한다.(그 밖에 기본 CS 적인 부분들도 하나씩 다룰예정 )

그중 오늘은 가비지 컬렉션에 대해서 알아보고 자바스크립트에서 가비지 컬렉션이 어떻게 발생하는지 알아보겠다.

가비지 컬렉션이란(GC)

이후 글은 가비지 컬렉션을 GC라고 칭한다. 


c, c++와 같은 저수준의 언어를 사용해 개발하면 malloc과 free 함수를 사용해서 직접 메모리를 할당하고 해제하며 개발할 수 있다. 직접적인 메모리 관리를 통해서 성능 최적화나 하드웨어의 코어적인 개발에 있어서 장점을 제공하지만, 메모리 관리는 개발자 본인이 해야 되기 때문에 메모리 오류나 누수가 발생할 우려가 있다.

저수준언어란?
컴퓨터가 직접 이해하고 실행할 수 있는 언어를 말함. 하드웨어단에서 가깝게 동작하며, 기계어(0,1의 이진형태)와 유사한 형태를 가짐. 



GC는 메모리 관리 기법 중 하나로, 개발자가 직접 메모리를 관리하는 부분을 대신해 자동으로 메모리의 할당과 해제를 처리해 주는 역할을 한다. 이는 개발자가 메모리 할당과 해제에 대한 부담을 덜어주는 동시에, 프로그램 실행 중 사용되지 않는 메모리를 자동으로 해제하여 메모리 누수를 방지할 수 있다. Java, Javascript, Python과 언어의 엔진내부에서 컴파일될 때, 이러한 GC를 사용한다.  
 

Javascript 가비지 컬렉션(GC)

자바스크립트에서도 사용하지 않는 메모리를 해제하기 위해서 GC를 사용하여 메모리를 관리한다. 자바스크립트는 v8엔진 내의에서 메모리를 관리한다. 
 

V8 엔진 

https://deepu.tech/memory-management-in-v8/

 
V8 엔진은 자바스크립트(javascript) 및 웹 어셈블리(webAssembly)에서 사용되는 엔진으로 Chorme 브라우저와 Nodejs 환경에서 javascript 코드를 실행시키기 위한 역할을 담당한다. AOT(Ahead-Of-Time) 컴파일 방식과 상반되는 인터프리터 언어의 컴파일 방식인 JIT(Just-In-Time) 방식을 사용하며 코드를 실행할 때, 실행 중인 코드를 컴파일함과 동시에 컴파일된 코드를 캐싱하여 재사용하여 반복 작업을 줄이는 역할을 한다. 
  

자바스크립트에서 GC는 V8엔진 내에서 수행된다. V8엔진은 메모리 관리를 위해 Heap, Stack 영역을 관리한다. 

 

Heap 

Heap 영역은 V8에서 동적으로 생성되는 데이터를 저장하는 영역이다. Heap은 메모리가 동적으로 할당되고 크기가 조정될 수 있다. GC 또한 Heap에서 발생한다. 새로운 객체가 생성될 때마다 메모리 할당이 생기고, GC는 이렇게 할당된 메모리에서 더 이상 필요하지 않은 객체를 탐지해 제거된다. V8의 Heap에 특징들을 간략하게 나열하면 다음과 같다. 

 

  • 동적으로 생성되는 데이터가 저장됨.
  • 크기가 동적으로 조정될 수 있음.
  • GC를 통해 더 이상 사용되지 않는 데이터가 정리됨.
  • 실제 GC가 발생하는 영역. 

Stack

Stack 영역은 함수 호출 및 변수 참조를 위한 메모리 공간이다. 자바스크립트에서 원시 타입의 데이터와 Heap 영역에 저장된 객체의 참조 정보가 Stack에 저장된다. Stack은 함수 호출 시 쌓이고 함수가 종료되면 해당 함수에 할당된 메모리 공간이 해제된다. V8의 Stack의 특징에 대해서 간략하게 나열하면 다음과 같다.

 

  • 함수 호출 및 변수 참조를 위한 메모리 공간
  • 원시 타입과 Heap 영역에 저장된 동적 데이터의 주소를 저장
  • LIFO(Last In, First Out) 구조를 가짐
     

V8 엔진의 GC

 

V8 GC는 The Generational Hypothesis이라는 가설을 사용하여 동작한다. 

 The Generational Hypothesis 이란?
- 대부분의 객체는 금방 접근 불가능한 상태(Unreachable) 된다.
- 새로운 객체가 오래된 객채보다 쓸모없어질 가능성이 더 높다. 
라는 전제의 가설.

 

이에 따라 V8 엔진에서는 Heap 영역에서 GC가 발생한다. 이러한 과정은 Minor GC와 Major GC로 나뉜다. 

 

 

Minor GC(스캔빈 저)

 

Minor GC는 새로운 객체가 생성될 때 발생하며, 이 과정에서 Young Generation과 Old Generation 영역이 관여한다. 

 

이중 Young Generation에서 사용하는 New Space와 Semi-space는 새로운 객체가 할당되는 영역으로 New Space는 From-space와 To-space로 구성되어 있다. 새로운 객체가 생성될 때, 처음 From-space에 할당되며, From-space에 객체가 계속해서 쌓이다가 일정 크기 이상이 차면 Minor GC에 의해 트리거 된다. 

 

Minor GC의 동작과정 

  1. 새로운 객체가 생성될 때마다 메모리가 From-space에 할당
  2. From-space가 일정 크기 이상 차면(1~8MB라고 함), Minor GC가 트리거가 되어서 From-space에 있는 객체들을 스캔하여 Reachable 하지 않은 객체들을 찾는다. 
  3. Reachable 하지 않은 객체들은 가비지로 표기되며, 해당 객체들은 메모리에서 해제된다.(free!!)
  4. Reachable 한 객체들은 To-space로 복사된다.
  5. To-space로 복사된 객체들은 새로운 객체로 간주해, 이후에 참조될 수 있다. 
  6. 이후 From-space와 To-space의 역할이 교체된다. To-space가 새로운 From-space가 되고 From-space는 다시 To-space가 된다. 
  7. 이러한 과정을 반복하면서 Minor GC의 작업이 완료된다. 

Minor GC를 수행하는 동안 Reachable 한 객체들 중 Old Space로 이동할 수 있는데, 이는 새로운 객체가 계속해서 참조될 경우 Old Space로 Promote 되어 메모리를 확보하는 과정을 말한다. Old Space는 Young Generation에 비해서 메모리가 크고, 오래 사용되는 객체들이 할당되는 공간이 기기에 새로운 객체가 Old Space로 이동하면 Old space의 메모리 관리를 위해서 Major GC가 필요해진다. 

Promte?
Promote는 가비지 컬렉션에서 객체를 한 세대의 메모리에서 다른 세대로 이동하는 과정을 의미한다. 즉, Young Generation -> Old Generation으로 이동하는 과정이라고 볼 수 있다. 

 

 

Major GC

 

Major GC는 Old Generation 영역에서 일어난다. Old Generation은 Young Generation보다는 메모리가 크고, 더 오랜 기간 사용되는 객체들이 할당되는 공간을 의미한다. Major GC는 주로 Old Generation의 영역이 가득 차거나 시스템 메모리가 부족할 상태에 발생하는데, 이때 GC가 Old Genertaion을 스캔하고, 더 이상 참조되지 않는 객체들을 제거하여 메모리를 회수하는 역할을 한다. 이때 Sweep and Markf라는 알고리즘과 Tri-color 알고리즘을 사용하여 메모리를 관리한다. 

 

Mark And Sweep

 

Major GC 과정 중에서 Old Generation에서 주로 발생하며, 해당 과정을 통해 더 이상 사용되지 않는 객체를 식별하고 메모리에서 제거하는 역할을 수행한다. 

 

Mark(식별)

  • GC가 객체의 사용여부를 식별하는 단계
  • 메모리에 있는 모든 객체를 순회하며, Reachable 한 객체들을 마킹함. 도달 가능한 객체는 가비지 컬렉션 대상이 아님
  • DFS 알고리즘을 활용한 전개 

 

Sweep(회수)

  • 마킹 완료 후, 메모리를 순회하며 마킹되지 않은 객체들을 식별함
  • 식별된 객체들을 UnReachable 한 객체로 판단해 GC 대상이 됨. 
  • 마킹되지 않은 객체의 메모리를 해제해 사용가능한 상태로 만듦. 

 

Mark and Sweep 알고리즘을 통해서 Major GC는 Old Space에 더 이상 필요하지 않은 객체들을 식별하고 해제하여 메모리를 효율적으로 관리한다.  
 

 

 

 

참고

 

 

🚀 Visualizing memory management in V8 Engine (JavaScript, NodeJS, Deno, WebAssembly)

Let us take a look at how the V8 engine for JavaScript & WebAssembly manages memory for Browsers and NodeJS.

deepu.tech

 

 

 

가비지 컬렉션

 

ko.javascript.info

 

 

자바스크립트 v8 엔진의 가비지 컬렉션 동작 방식 | 카카오엔터테인먼트 FE 기술블로그

권현빈(vinny) 스포츠를 좋아하는 개발자입니다. 요즘은 정적인 취미를 해보려 합니다.

fe-developers.kakaoent.com

 

 

[JavaScript] V8 Garbage Collection

V8 Garbage Collection 💡 V8 엔진에서 JavaScript Garbage Collection 동작 방식을 정리합니다. 1. Garbage Collection Garbage Collection을 단어 그대로 해석하면 ‘쓰레기 수집’입니다. 프로그래밍에서 더 이상 사용하

iyu88.github.io

 

'Language > JS & TS' 카테고리의 다른 글

[JS] 콜백(Callback) 함수  (0) 2024.05.19