[JavaScript] 변수와 메모리

Joowon Jang·2024년 6월 22일

JavaScript

목록 보기
3/17

( 정재남 -'코어 자바스크립트' 참고 )

JavaScript의 메모리

컴퓨터는 모든 데이터를 0과 1로 기억한다.
0 또는 1을 표현하는 하나의 메모리 조각을 bit(비트)라고 하며, 메모리는 매우 많은 bit들로 이루어져 있는데, 각 bit는 고유한 식별자를 통해 위치를 확인할 수 있다.
표현할 수 있는 값을 늘리고 검색 효율도 높이기 위해 몇 개의 bit를 하나의 단위로 묶게 된다.
1byte(바이트) = 8bit

C/C++, Java 등의 정적 타입 언어는 메모리 낭비를 최소화하기 위해 데이터 타입별로 할당할 메모리 영역을 2byte, 4byte 등으로 나누어 정해놓았다.
하지만, JavaScript는 메모리 용량이 과거보다 커진 상황에서 만들어졌기 때문에, 메모리 관리 측면에서 상대적으로 자유로웠고, 더 큰 영역을 하나로 묶어서 데이터 타입 간 변환을 걱정할 상황이 훨씬 줄어들었다.

변수의 선언과 할당

식별자와 변수

변수(variable): 변할 수 있는 데이터.
식별자(identifier): 데이터를 식별하는 데 사용하는 이름. 변수명.

원시타입 변수의 선언과 할당

변수의 선언 및 할당 과정이 메모리에서 어떻게 동작하는지 간략하게 알아보자.
메모리의 주소와 구조는 실제 메모리와 다를 수 있고, 동작하는 방식만을 설명하기 위한 그림을 사용했다.

var a;

위의 코드에서는 하나의 변수를 선언하고, 그 변수의 이름(식별자)을 'a'로 정했다.
이렇게 변수를 선언하게 되면, 아래 그림처럼 메모리의 한 공간을 차지하게 된다.

원시타입 메모리1

하지만 아무 값도 할당하지 않았기 때문에 그저 공간만 차지할 뿐이다.
그럼 이 변수 a에 값을 할당하면 어떻게 될까?

var a;
a = 10

원시타입 메모리2

이렇게 변수 a에 10이라는 값을 할당하게 되면,

  1. 변수 영역에 a의 공간을 확보한다.
  2. 데이터 영역에 값(10)이 존재하는지 탐색한다.
  3. 값(10)을 찾지 못하면, 데이터 영역의 한 곳에 값(10)을 저장한다.
  4. 값(10)을 저장한 데이터의 주소를 변수 a의 공간에 저장한다.

위의 그림처럼 a 변수는 어떤 값을 가진 다른 영역을 참조하는 것이다.

그렇다면, 메모리에 존재하는 값을 변수에 할당한다면 어떻게 될까?

var a = 10;
var b = 10;

원시타입 메모리3

위의 그림과 같이 다음의 과정으로 할당하게 된다.

  1. 변수 영역에 b의 공간을 확보하다.
  2. 데이터 영역에 값(10)이 존재하는지 탐색한다.
  3. 값(10)이 존재하므로 해당 데이터의 주소를 변수 b의 공간에 저장한다.

변수의 값이 변경되는 과정도 살펴보자.

var a = 10;
var b = 10;
a = 15;

원시타입 메모리4

기존의 값을 변경하는 것이 아니라, 아래의 과정을 거치는 것을 알 수 있다.

  1. 데이터 영역에 값(15)이 존재하는지 탐색한다.
  2. 존재하지 않으면 데이터 영역의 새로운 공간에 값(15)를 저장한다.
  3. 새로운 데이터의 주소(502)를 변수 a의 공간에 저장한다.

숫자 뿐만 아니라 문자열 등의 다른 자료형들도 동일하게 동작하며,
새로운 값을 할당할 때 뿐만 아니라 기존의 값을 연산할 때에도 새로운 해당 메모리의 값을 바꾸는 것이 아니라 연산 결과를 데이터 영역에서 탐색 후 새로 저장하는 것이다.

몇가지 예시를 보면,

var c = 10;
var d = 10;
c = d + 5; // 15

여기서 c는 d와 같은 주소를 참조하다가, 15라는 새로운 값을 가지게 되면서 원래 참조하던 주소가 아닌 15라는 값을 가진 다른 메모리의 주소를 참조하게 된다.

var str = 'hello';
str = str + 'World'; // 'helloWorld'

여기서도 마찬가지로 'hello'를 가지는 메모리를 놔두고 다른 메모리의 'helloWorld'를 참조하게 된다.

참조타입(객체)의 선언과 할당

그렇다면 객체는 메모리에서 어떻게 동작할까?

var user = {
  name: 'joowon',
  age: 27
}

위와 같은 user 객체를 예로 들어보자.

객체 메모리

다음과 같은 과정을 거쳐서 위의 그림처럼 구성된다.

  1. 변수 영역에 user의 공간을 확보한다.
  2. 임의의 데이터 영역에 데이터를 저장하려고 보니, 여러개의 프로퍼티로 이루어진 데이터이다.
  3. 별도의 변수 영역(@701~702)을 확보하고 그 주소를 데이터 영역(@501)에 저장한다.
  4. 데이터 영역에 각각의 프로퍼티(@701, @702)에 필요한 값이 있는지 탐색한다.
  5. 데이터 영역에 해당 값이 존재하면 그 주소를 각각의 프로퍼티에 전달하고, 존재하지 않으면 새로운 공간을 확보한 후 데이터를 저장하고 그 주소를 프로퍼티에 전달한다.

ES6에서 등장한 let과 const
let 변수가 참조하는 메모리 주소를 변경할 수 있음. (값 변경 가능)
const 상수가 참조하는 메모리 주소를 변경할 수 없음. (값 변경 불가)

하지만 객체의 경우 const로 선언해도 프로퍼티들의 값을 변경할 수 있는데,
왜냐하면 객체가 참조하는 주소는 변경할 수 없지만, 객체 안의 프로퍼티들이 참조하는 주소는 고정되지 않았기 때문이다.
그래서 const 상수에 새로운 객체를 할당하는 것은 불가능 하지만 이미 할당되어 있는 객체의 프로퍼티를 변경하는 것은 가능한 것이다.

profile
깊이 공부하는 웹개발자

0개의 댓글