[JS] V8 엔진의 메모리 모델

유니·2022년 7월 24일
0

JavaScript

목록 보기
5/9

V8 엔진의 메모리 모델

메모리 구조


V8 엔진의 메모리에서 실행되고 있는 프로그램을 Resident Set이라고 하며 크게 Heap memoryStack으로 나누어집니다.

Heap memory

참조형 데이터의 실체와 동적 데이터가 저장되는 장소입니다.

  • New space (Young generation)
    최근에 만들어진 데이터가 저장되는 장소이며 Minor GC의 타겟이 됩니다. Old 영역에 비해 매우 작아 가비지 컬렉션이 매우 빈번하게 발생됩니다.

  • Old space (Old generation)
    New 영역에서 살아남은 객체들이 이동되는 곳입니다. 이후에는 Major GC에 의해 관리됩니다.
    Old pointer space(살아남은 객체들이 저장), Old data space(살아남은 리터럴이 저장) 부분으로 나눠집니다.

  • Large object space
    다른 영역으로는 감당하지 못하는 매우 큰 객체들이 저장되어 있습니다. 가비지 컬렉터에 의해 이동되지 않습니다.

  • Code space
    컴파일러의 의해 컴파일된 코드가 저장되는 장소입니다. 유일하게 실행가능한 데이터가 저장되어있으며, Large object space에 할당 될 수도 있습니다.

Stack

변수, 함수, 클래스, 함수 프레임과 같은 정적 데이터가 저장됩니다.
함수, 클래스는 미리 스택에 올려놓으며, 변수는 해당 스코프를 만날 때 스택에 올립니다.
스코프를 벗어나면 스택에 올라와있던 변수, 함수, 매개변수등을 해제합니다.
함수가 종료되어도 아직 외부에서 참조되고 있는 지역변수가 있다면 스택이 아닌 힙으로 이동되어 파기되지 않습니다. 이것이 클로저입니다.

메모리 관리

  • Minor GC (Scanvenger)

    힙의 New 영역을 관리합니다. 작은 크기의 space를 매우 잦은 주기로 순회합니다.
    두 작은 영역으로 나누어져 있고 From-영역, To-영역으로 부릅니다.
    [동작 방식]
    1️⃣ 새로운 데이터를 From-영역의 빈 공간에 할당하려고 시도합니다.
    2️⃣ 할당할 수 없다면, 스케벤져를 실행시켜 살려야 할 데이터만 From-영역To-영역으로 이동시킵니다. (이 과정에서 To-영역이 자동으로 압축되어 단편화를 줄입니다.)
    3️⃣ From-영역에 남아있는 데이터를 제거합니다.
    4️⃣ 이제 To-영역From-영역처럼 사용합니다.
    5️⃣ 두번의 Minor GC 과정에서 생존한 객체들은 Old 영역 으로 이동합니다.
  • Major GC
    힙의 Old 영역를 관리합니다. Minor GC 보다 긴 주기로 동작합니다.
    • 초기의 자바스크립트 : 참조 카운팅 방식을 사용했습니다. 누구도 참조하지 않는 데이터를 가비지로 취급합니다.
      이 방식은 순환참조가 발생하는 데이터를 반환하지 못하는 취약점이 존재합니다. 이 경우 메모리 누수가 발생합니다.
    • 최근의 자바스크립트 : Mark Sweep 방식을 채택하여 Mark - Sweep - Compact(디스크 조각 모음) 과정으로 메모리를 관리합니다. Root에서 닿을 수 없는 데이터를 가비지로 취급합니다. Root에서 닿을 수 있는 데이터만 Mark 하고 그 외에는 Sweep 하는 방식입니다.

      Mark : 힙 메모리를 방향 그래프로 간주해 DFS 방식으로 사용중인 객체를 식별합니다.
      Sweep : 가비지 컬렉터가 힙 메모리를 순회하면서 활성 상태로 표시되지 않은 객체들의 메모리 주소를 기록합니다.
      Compact : 단편화를 줄이기 위한 압축단계입니다.
profile
추진력을 얻는 중

0개의 댓글