자바스크립트 메모리 상에서 데이터 관리(가변성, 불변성)

sith-call.dev·2022년 3월 24일
0

01. 데이터 타입의 종류

기본형 : 값이 담긴 주솟값을 바로 복제

참조형 : 값이 담긴 주솟값들로 이루어진 묶음을 가리키는 주솟값을 복제

기본형은 불변성을 가지고, 참조형은 가변성을 가진다.

02. 데이터 타입에 관한 배경지식

1-2-1 메모리와 데이터

  • 1비트 단위 묶음 체계
    • 주소의 개수 : 8개
    • 한 단위 당 표현 가능한 데이터 개수 : 2개
  • 2비트 단위 묶음 체계
    • 주소의 개수 : 4개
    • 한 단위 당 표현 가능한 데이터 개수 : 4개
  • 4비트 단위 묶음 체계
    • 주소의 개수 : 2개
    • 한 단위 당 표현 가능한 데이터 개수 : 16개

이처럼 단위 묶음 체계의 비트 수를 늘리면, 데이터 주소의 개수는 줄어들고, 한 단위 당 표현 가능한 데이터의 개수는 늘어난다.

데이터 주소의 개수가 줄어들수록 검색할 대상이 줄어들기 때문에 검색 시간을 줄어들게 된다. 그러나 동시에 메모리에 적재할 수 있는 데이터의 개수는 줄어든다. 동시에 한 단위의 데이터가 표현할 수 있는 정보의 개수는 늘어난다.

이런 관계가 있기에 단위 묶음 당 비트의 수를 늘리는건 trade-off가 존재한다.

그래서 가장 적절한 크기의 단위 묶음 당 비트의 수를 8개로 설정한 것이다.

각각의 자료형마다 필요한 데이터 표현의 개수만큼 비트수를 할당해주는 등의 방법을 통해 제한된 메모리를 효율적으로 사용했었다. 그렇기에 서로 할당된 비트 수가 다른 자료형끼리는 형변환을 할 때 번거로운 작업을 필요로 했다.

그러나 자바스크립트는 메모리 영역이 풍족하게 제공된 환경이기에 숫자의 경우 정수형인지 부동소수형인지 구분하지 않고 64비트, 즉 8바이트를 할당한다. 그래서 번거로운 형변환 작업을 거치지 않아도 된다.

1-2-2 식별자와 변수

변수 : 변할 수 있는 데이터

식별자 : 변수의 이름

03. 변수 선언과 데이터 할당

콜스택과 메모리힙에 각각 변수 영역이 존재하고 하나의 데이터 영역을 공유한다.

1-3-1 변수 선언

변수란 최종적으로 변경 가능한 데이터가 담길 수 있는 공간 또는 그릇을 말한다.

그래서 메모리에 할당된 변경 가능한 데이터에 접근하기 위해선 변수 이름을 필요로 한다. 그러면 컴퓨터는 해당 변수의 이름을 주소로 갖는 영역에 접근하여 데이터를 읽는다.

1-3-2 데이터 할당

데이터의 성질에 따라 데이터가 할당되는 메모리 영역이 다르다.

변수 영역과 데이터 영역으로 메모리를 구분하여 데이터를 할당시킨다.

이렇게 메모리 영역을 구분한 이유는 다음과 같다.

  1. 데이터 변환을 자유롭게 할 수 있게 함
  2. 메모리를 더욱 효율적으로 관리하기 위함

데이터의 크기가 가변적이기 때문에 이를 효율적으로 관리하기 위해 변수 영역과 데이터 영역을 구분시켜 놓은 것. 예를 들어 가변적인 크기의 데이터들이 할당되고 해제된다면, 메모리 영역에는 공간들이 전부 조각난 상태가 될 것이다. 이런 상황을 효과적으로 관리하기 위해서 변수 영역과 데이터 영역을 나눈 것이다.


var a;

a = 'abc';

a = 'abcdef'


데이터 영역에 데이터를 새로 만들어서 대응시킨다.

04. 기본형 데이터와 참조형 데이터

1-4-1 불변값

변수와 상수를 구분하는 성질은 ‘변경 가능성’이다.

불변값과 상수를 같은 개념으로 오해하기 쉬운데, 이 둘을 명확히 구분할 필요가 있다.

변수와 상수를 구분 짓는 변경 가능성의 대상은 변수 영역 메모리이다.

불변성 여부를 구분할 때의 변경 가능성의 대상은 데이터 영역 메모리이다.

변수와 상수는 변수 영역에서 데이터 할당이 이뤄진 변수에 다른 데이터를 재할당할 수 있는지 여부가 관건이다.


var a = 'abc';
a = a + 'def';

var b = 5;
var c = 5;
b = 7;


💡 기본형은 불변성을 띠고 있기 때문에 데이터 영역에서 값을 변경하지 않고 새로운 데이터를 할당하여 대입한다.

💡 데이터 영역을 공유하고 있기 때문에 같은 데이터를 바라보게 된다.

💡 마찬가지로 기본형은 메모리 데이터 영역에서 불변성을 띄고 있기 때문에 새로운 데이터를 할당하여 대입한다.

1-4-2 가변값

참조형 데이터를 변수에 할당하는 과정을 살펴본다. 기본형 데이터와의 차이는 ‘객체의 변수(프로퍼티) 영역’이 별도로 존재한다는 점이다. 이로인해 참조형 데이터는 가변형이라고 부른다.


var obj1 = {
	a:1,
	b:'bbb'
}


var obj1 = {
	a:1,
	b:'bbb'
};
obj1.a = 2;


💡 데이터의 값은 달라졌다. 그럼에도 불구하고 변수가 가리키고 있는 데이터 영역의 주소는 일정하다. 즉, 데이터 영역의 주소는 변화지 않았음에도 실질적으로 데이터의 값이 바뀌는 이러한 특성을 가변형이라고 한다.
var obj = {
	x:1,
	arr:[1,2,3]
}

💡 참조형 데이터를 가리키는 포인터들만 표현을 했다. 이처럼 변수 영역은 참조 데이터의 개수만큼 생성된다.
var obj = {
	x:1,
	arr:[1,2,3]
}
obj.arr = 'str'


💡 어떤 데이터에 대해 자신의 주소를 참조하는 변수의 개수를 참조 카운트라고 한다. 위처럼 참조 카운트가 0인 메모리 주소는 가비지 컬렉터의 수거 대상이 된다.

1-4-3 변수 복사 비교

var a = 10;
var b = a;

var obj1 = { c:10, d:'ddd'}
var obj2 = obj1;

💡 같은 포인터를 갖고 있다는 것에 주목.
var a = 10;
var b = a;
var obj1 = {c:10, d:'ddd'};
var obj2 = obj1;

b = 12;
obj2.c = 20

a !== b // True
obj1.c === obj2.c // True




var a = 10;
var b = a;
var obj1 = {c:10, d:'ddd'};
var obj2 = obj1;

b = 15;
obj2 = {c:20, d:'ddd'};



1-5-2 얕은 복사와 깊은 복사

얕은 복사(shallow copy) : 아래 단계의 값만 복사하는 방법

깊은 복사(deep copy) : 내부의 모든 값들을 하나하나 찾아서 전부 복사하는 방법

얕은 복사의 문제점은 사본을 바꾸면 원본도 바뀐다는 점이다.

깊은 복사는 모든 값이 동일한 또 다른 객체를 생성하여 반환하기 때문에 사본을 바꿔도 원본에 영향이 없다.


var obj1 = {a:1,b:'abc'};

var obj2 = obj1; // shallow copy

var obj3 = {a:1,b:'abc'}; // deep copy (rough expression)

콜스택과 메모리힙

위와 같은 설명은 자바스크립트 인터프리터의 콜스택과 메모리힙과는 약간 차이나는 부분이 있다. 그러나 콜스택은 변수 영역에 대응하면 되고, 메모리힙은 어떤 객체의 변수 영역에 대응하면 된다. 그리고 데이터 영역은 아예 자바스크립트 인터프리터가 따로 관리한다고 생각하면 될 듯 하다. 그러나 이러한 이해는 내가 추상적으로 이해하기 위해서 임시적으로 구분해놓은 것이고, 자바스크립트 인터프리터의 구체적인 구조를 기반으로 한 것은 아니다. 그러니 이해용으로만 글을 읽으면 될 듯 하다.


참고자료

코어 자바스크립트

profile
Try again, Fail again, Fail better

0개의 댓글