본문 바로가기

1.웹개발/JS

변수와 메모리 적재 과정

변수는 필요할까요?

 

다음과 같은 코드가 있다고 가정합니다

 

console.log(1)

console.log('heo')

 

console api의 log 메서드를 통해, 1과 heo를 출력하였습니다.

 

문제는, 이를 '재사용'할때 발생합니다

 

1을 재사용 해서 출력할 경우 아래와 같이 될 것 입니다.

 

console.log(1)
console.log(1)
console.log(1)

큰 문제는 없어보이는데, 모든 1에 2를 더해야 한다고 가정한다면

 

console.log(1+2)
console.log(1+2)
console.log(1+2)

이렇게 바뀔 것이며 나아가 이런 작업을 무한대로 반복한다면? 반복 작업을 많이 수행할 것 입니다.

 

또한, '특정' 1만 선택해서 3을 더한다면? "어떤"기준으로 1을 선택할 수 있을지 알 수 없습니다.

 

그래서 변수는 프로그래밍에서 데이터를 관리하는 필수적입니다.

 

1 + 1 이라는 코드는, 메모리에

참고 그림 1

참고 그림 1은 32비트 컴퓨터의 4GB 메모리를 그림으로 표현하였습니다. 하단에 빗금표시는 1GB정도의 커널을 가지고

3GB의 유저영역중, "임의의" 공간에 피연산자 두개가 들어가 있으며, 연산 결과가 적재되어 출력됩니다.

 

문제는, 0x000004라는 메모리 주소공간에 식별자가 없어 "재사용" 할 수 없습니다.

-> 현재는 0x000004라는 메모리 주소를 알지만, 이에 직접 접근하는 것은 위험하므로 배제합니다.

 

변수란 한개의 값을 저장하기 위한 메모리 공간 또는 메모리 공간의 주소에 붙인 이름으로 정의하며,

값의 위치를 나타냅니다

 

여기서, 변수에 여러개의 값을 담고싶을때 (객체, 배열)같은 자료구조들이 등장하며

 

자바스크립트에서 메모리에 변수가 적재되는 과정에 따라 호이스팅도 개념도 출현하게 됩니다.

 

var name = 'HEOBEOMSUNG";

es6이전, 과거의 변수 선언 & 할당문입니다. 한줄의 코드는 2단계에 거쳐서 동작합니다.

 

var name;
name = "HEOBEOMSUNG";

위는 name이라는 변수 선언(변수 선언문)이고

아래는 변수 할당(할당문)입니다.

 

우선 위의 코드를 실행하게 될때, 

참고 그림2

참고 그림2와 같은 메모리가 존재할때,

참고 그림 3

참고 그림 3처럼 임의의 참조되지 않은 메모리 공간(0x000002)를 확보하고 (안에 어떤 값이 존재할지는 모릅니다.)

참고 그림4

참고 그림4 처럼, 변수의 선두 메모리셀에 name이라는 식별자를 바인딩합니다. 

참고 그림5

그 후, 메모리 공간에 undefined로 암묵적으로 할당되어 초기화 합니다.

 

var name;
name = "HEOBEOMSUNG";

이것이 1번라인의 동작이며,

참고 그림6

2번라인에서, name이라는 식별자로 0x000002라는 메모리를 찾아내어 값을 재할당하는게 아니라

0x000004라는 새로운 메모리 주소에 name이라는 식별자를 바인딩하고 값을 할당하며, 기존의 0x000002의 메모리는

쓰레기값으로 남게됩니다.

 

이 과정을 거치기 때문에

 

console.log(name);
var name = "HEOBEOMSUNG";

상단의 코드 결과는 undefined를 반환하며 (브라우저에서 개발자 도구에서 출력했을땐 name이라는 식별자가 이미 사용되어있는 것으로 추측되기에 test라는 식별자를 사용)

 

console.log(name);
var name;
name = "HEOBEOMSUNG";

위와 같은 코드로 나뉘고 자바스크립트에선 실행전에 "선언문"들만 미리 끌어올려져서, 메모리에 적재되기 때문에

 

var name; // 런타임이전 호이스팅에 의해 끌어올려짐
console.log(name);
name = "HEOBEOMSUNG";

에러가 발생하지않고 undefined가 출력됩니다. (변수 호이스팅)

 

변수는 3단계의 과정을 거칠 수 있으며,

 

1.선언 단계

2.초기화 단계

3.할당 단계

 

var의 경우 1,2가 동시에 진행되었습니다.

 


다음과 같은 코드가 있습니다.

 

var height = 183;

참고 그림7

height는 number 데이터타입으로, 8바이트 만큼의 메모리 공간을 차지하며 하단 그림과 같습니다.

0x0000aab3 이라는 메모리에 height 라는 변수 식별자를 바인딩하였고, 183이라는 이진수로  10110111로,

"가장 마지막 셀 = 0x000aaba"에 저장되어 있습니다. 183이 256(2^8)보다 작기때문입니다. (1Byte)

 

256을 저장한다면 100000000로, 자리 올림이 발생해서 가장 하단의 메모리(0x000aaba)는 00000000이 저장 되어있고

0x000aab9에는 00000001이 저장되어 있습니다. 이는 메모리를 세로가 아닌 가로로 이해하면 쉽습니다.

 

참고 그림8

 

위 그림은, 십진수 256을 메모리에 적재하였을때, 2진수로 넣은 메모리의 가장 하단(?), 끝 부분입니다.

아래 그림은 십진수 183을 메모리에 적재하였을때 2진로 넣은 메모리의 끝부분입니다.

 

그림 7의 0x0000aab3을 시작으로, 0x0000aaba까지를 세로가 아닌 가로로 본다면, 뒷자리부터 표시 되고

나머지는 0으로 채워집니다.

 

이를 통해, 자바스크립트는 2의 2^64까지 표현할 수 있는게 아닌가 추측을 하였는데, (음수 포함하면 줄어들겠죠)

MDN에서는 -(2^53 -1) 와 2^53 -1까지, 부동 소수점을 사용하다보니 실수부분에서 문제가 생길 수 있어서

 

Number.MAX_SAFE_INTEGER
9007199254740991
Number.MAX_VALUE
1.7976931348623157e+308

Number 객체에 있는 메서드를 통해 알아보았습니다. 마지막 2^64가 아닌이유에 대해서 알아보고 포스트 하겠습니다.

반응형

'1.웹개발 > JS' 카테고리의 다른 글

[JS]비동기 프로그래밍  (0) 2022.07.27
[JS] 배열 for ... of 문  (0) 2022.04.26
for문의 동작순서  (0) 2020.10.13
var와 let/const의 차이  (0) 2019.08.14
[JS] 자바스크립트 ES5 ES6 차이  (2) 2019.08.12