쫌만알자! (15) - 자바스크립트의 메모리

Yeony (Nayeon Kim) · 2022-11-02

C 와 같은 저급 언어는 메모리 관리를 명시적으로 합니다. 반면 자바스크립트에서는 어떤 작업(객체 생성, 문자열 할당 등...)을 할 때 메모리가 할당되고, 사용되지 않을 때에 자동으로 메모리가 반환됩니다. 이를 가비지 컬렉션(garbage collection)이라고 합니다.

사실 ECMAScript 사양에서는 변수를 통해 메모리를 어떻게 관리해야 하는지 나와있지 않습니다. 또한 자바스크립트가 자동으로 관리해주기도 합니다.

그래도 자바스크립트 코드가 메모리에 어떻게 저장되는지, 메모리에 대해 대략적으로 알고 가보도록 합시다.

메모리란?

변수 사용하기 에서 메모리를 언급한 적이 있습니다. 변수를 하나의 값을 저장할 수 있는 메모리 공간 이라고 말했었죠.

이렇듯 메모리는 자바스크립트 엔진 내에서 데이터를 저장하고, 외부에서 접근할 수 있는 메모리 주소를 제공합니다.

메모리 LifeCycle

메모리는 생명주기가 있습니다. 생성되고, 사용된 후, 소멸되는 과정이 생명 주기입니다.

메모리의 라이프사이클은 대부분의 언어가 비슷합니다.

  1. 필요할 때 할당
  2. 할당된 메모리 사용
  3. 필요하지 않으면 해제

이 과정 중 2번은 모든 언어에서 명시적으로 사용되나, 1번과 3번은 고수준언어에서는 암묵적으로 사용됩니다. 자바스크립트는 고급언어이기 때문에 해당 과정이 암묵적으로 진행됩니다.



스택 & 힙

우리는 이제 자바스크립트 엔진은 필요하면 메모리를 할당하고, 필요하지 않으면 해제한다는 것을 알았습니다. 그럼 어디에 어떻게 저장되는 걸까요?

데이터를 저장할 수 있는 위치는 2 가지가 있습니다. 바로 스택(Stack)과 힙(Heap)입니다.

스택: 정적 메모리 할당

자바스크립트는 정적 데이터를 스택(Stack) 형태로 저장합니다. 여기서 정적 데이터란, const 처럼 변하지 않는, 즉 자바스크립트 엔진이 컴파일 시에 크기를 알고 있는 데이터를 일컫습니다.

엔진은 크기가 변경되지 않는다는 것을 알고 있으므로, 각 값에 대해 고정된 메모리 크기를 할당합니다.

const alwaysTrue = true; const pie = 3.14;

Stack

여기에는 기본 값(string , numbers , booleans , undefined 및 null)과 개체 및 함수를 가리키는 참조(reference)가 포함됩니다.

힙: 동적 메모리 할당

동적 데이터는 런타임 시 데이터 크기를 알게 되는 데이터입니다. 크기를 알지 못하니 고정된 메모리 크기를 할당하지 못합니다. 필요에 따라 더 많은 공간을 할당하게 됩니다.

이런 방식을 동적 메모리 할당이라고도 합니다.

스택과 힙의 차이는 이렇습니다.

Stack Heap
Primitive values and references Objects and functions
컴파일 시 사이즈를 알고 있음 런타임 시 사이즈를 알게 됨
고정된 메모리 할당 각각에 제한된 메모리 없음



자바스크립트의 참조(Reference)

자바스크립트에서 모든 변수는 먼저 스택에 저장됩니다.

만약 원시 값(primitive)이 아닌 경우, 스택에는 힙에 저장된 참조가 저장됩니다.

const user = { id: 1, name: 'Yeony', age: 24 } const name = 'Nayeon'; function add(x, y) { return x + y; } const newUser = user;

Stack and Heap

위 코드와 그림을 통해 각각의 값들이 어떻게 저장되는지 알 수 있습니다. 여기서 주의해야 할 점은, usernewUser가 같은 객체를 **참조(Reference)**하고 있다는 것입니다.

같은 객체를 참조한다는 의미는 한 객체의 프로퍼티 값이 바뀌면 그 객체를 참조하고 있는 개별적인 변수의 프로퍼티 값이 다 바뀐다는 것입니다.

const user = { id: 1, name: 'Yeony', age: 24 } const newUser = user; console.log(newUser.name); // 'Yeony' // user 객체의 name 변경 user.name = 'Nayeon'; console.log(newUser.name); // 'Nayeon' // newUser 객체의 name 변경 newUser.name = 'Kim'; console.log(user.name) // 'Kim'

이렇게 두 개의 변수가 하나의 개체를 가리키고 있기 때문에 값이 같이 바뀌게 됩니다.

다음 글에서는 참조 값과 관련된 복사에 대해 알아보도록 하겠습니다.



Reference

메모리 관리와 가비지 컬렉션를 좀더 알아보고 싶다면 아래 글을 참고해주세요.

Memory management JavaScript's Memory Management Explained


객체란 무엇일까? 👈 이전 글 보기
얕은 복사와 깊은 복사 👈 다음 글 보기


쫌만알자
Loading script...
© 2022 Nayeon Yeony Kim