본문 바로가기
개인공부/JavaScript

메모리와 데이터

by 왕큰새 2020. 7. 27.
728x90

컴퓨터는 모든 데이터를 0 또는 1로 바꿔 기억한다. 

0 또는 1만 표현할 수 있는 하나의 메모리 조각을 비트(bit)라고 하고, 메모리는 많은 비트들로 구성되어 있다.

 

각 비트는 고유한 식별자(unique identifier)를 통해 위치를 확인한다.

 

자주 사용하지 않을 데이터를 표현하기 위해 빈 공간을 남겨놓기보다는 표현 가능한 개수에 어느 정도 제약이 따르더라도 크게 문제가 되지 않을 적정한 공간을 묶는 편이 낫다. 이런 고민의 결과로 바이트(Byte)라는 단위가 생기게 되었다.

 

1바이트는 8개의 비트로 구성돼 있다. 1비트마다 0 또는 1의 두 가지 값을 표현할 수 있으므로 1바이트는 총 256(2^8) 개의 값을 표현할 수 있다. 2바이트는 비트 16개이므로 65536(2^16) 개의 값을 표현할 수 있다.

 

메모리 용량이 부족했던 시절에는, C/C++ , Java 정적 타입 언어는 메모리 낭비를 최소화시키기 위해, 데이터 타입을 2바이트, 4바이트 이런 식으로 나눠놓았다. 메모리 용량이 부족했을 시절에는, 사용자 입장에서 형 변환이 번거롭지만, 불가피한 선택이었다. 

 

하지만 현재에는, 메모리 용량이 월등히 커졌기 때문에, 자바스크립트는 좀 더 넉넉히 할당 하였다. 

숫자의 경우 정수형인지, 부동소수형인지를 구분하지 않고, 64비트 즉, 8바이트를 확보한다. 

그래서 자바스크립트의 경우는 형변환을 걱정해야 하는 상황이 조금 줄어들었다.

 

앞서, 각 비트는 고유한 식별자를 지닌다고 했다. 바이트 역시 비트의 식별자로 위치를 파악할 수 있을 것이다. 모든 데이터는 바이트 단위의 식별자, 정확하게는 메모리 주 솟값(memory address)을 통해 서로 구분하고 연결할 수 있다.

 

 

 

 

식별자와 변수 

 

변수 - 변할 수 있는 수 (숫자가 아니어도 된다. 변할 수 있는 어떠한 데이터)

 

식별자 - 어떤 데이터를 식별하는 데 사용되는 이름, 즉 변수명

 

 

 

 

변수 선언

 

 

var a;

 

풀어쓰면, 변할 수 있는 데이터를 만든다. 이 데이터의 식별자는 a로 한다.

변수란, 변경 가능한 데이터가 담길 수 있는 공간 또는 그릇 

 

 

주소 ----- 1002 1003 1004 1005 ----
데이터     이름: a
값: 
     

 

var a; 라는 명령을 받는 컴퓨터는 비어있는 공간 하나를 확보한다. 

임의로 1003번으로 정하고, 이 공간의 이름(식별자)을 a라고 지정한다.

여기까지가 변수의 선언 과정이다.

 

이후 , 사용자가 a에 접근하고자 하면 컴퓨터는 메모리에서 a라는 이름을 가진 주소를

검색해 해당 공간에 담긴 데이터를 반환할 것이다.

 

 

var a; // 변수 a 선언

a = 'abc'; // 변수 a에 데이터 할당

var a = 'abc'; // 변수 선언과 할당을 한 문장으로 표현

선언과 할당을 동시에 하던, 두 문장으로 나누어 명령하든, 자바스크립트 엔진은 결국 같은 동작을 수행한다.

 

할당 과정에서, a라는 이름을 가진 주소를 검색해서 그곳에 문자열 'abc'를 할당하면 될 것 같다.

 

하지만, 해당 위치에 'abc'를 직접 저장하지 않는다.

 

데이터를 저장하기 위한 별도의 메모리 공간을 다시 확보해, 문자열 'abc'를 저장하고, 

그 주소를 변수영역에 저장하는 식으로 이뤄진다.

이제부터 데이터의 성질에 따라 '변수 영역' , '데이터 영역'으로 구분하겠다.

 

변수 영역

주소 ---- 1002 1003 1004 1005
데이터     이름:a
값:  @5004
   

데이터 영역

주소 ---- 5002 5003 5004 5005
데이터       'abc'  

 

 

1. 변수 영역에서 빈 공간(@1003)을 확보한다.

 

2. 확보한 공간의 식별자를 a로 지정한다.

 

3. 데이터 영역의 빈 공간(@5004)에 문자열 'abc'를 저장한다.

 

4. 변수 영역에서 a라는 식별자를 검색한다.(@1003).

 

5. 앞서 저장한 문자열의 주소(@5004)를 @1003의 공간에 대입한다.

 

 

왜 변수 영역에 값을 직접 대입하지 않고 번거롭게 한 단계를 더 거치는 것일까?

 

이는 데이터 변환을 자유롭게 할 수 있게 함과 동시에 메모리를 더욱 효율적으로 관리하기 위한 고민의 결과이다.

이전에, 자바스크립트는 숫자형 데이터에 대해 64비트(8바이트)의 공간을 확보한다고 했다.

반면, 문자열은 정해진 규격이 없다. 한 글자 마자 영어는 1바이트, 한글은 2바이트 등으로

각각 필요한 메모리 용량이 가변적이며, 전체 글자 수 역시 가변적이기 때문이다.

 

만약, 미리 확보된 공간 내에서만 데이터 변환을 할 수 있다면 변환한 데이터를 다시 저장하기 위해서는

'확보된 공간을 변환된 데이터 크기에 맞게 늘리는 작업'이 선행되야 할 것이다.

 

해당 공간이 메모리 상의 가장 마지막에 있었다면, 뒤쪽으로 늘리기만 하면 되지만 중간에 있는 데이터를 늘려야 하는 상황이라면 해당 공간보다 뒤에 저장된 데이터들을 모두 뒤로 옮기고, 이동시킨 주소를 각 식별자에 다시 연결하는 작업을 해야 할 것이다. 효율적으로 문자열 데이터의 변환을 처리하려면 변수와 데이터를 별도의 공간에 나누어 저장하는 것이 최적이다.

 

 

문자열 'abc'의 마지막에 'def'를 추가하라고 하면 컴퓨터는 앞서 'abc'가 저장된 공간에 'abcdef'를 

할당하는 대신, 'abcdef'라는 문자열을 새로 만들어 별도의 공간에 저장하고, 그 주소를 

변수 공간에 연 갈한다. 

기존 문자열에 어떤 변환을 가하든 상관없이 새로 만들어 별도의 공간에 저장한다.

 

주소 ---- 1002 1003 1004 1005 ----
데이터     이름:a
값: @5005
     
주소 ---- 5002 5003 5004 5005  
데이터       'abc' 'abcdef'  

변수 영역의 값이 @5004 에서 @5005로 변경되었다.

 

 

다른 예로, 500개의 변수를 생성해서 모든 변수에 숫자 5를 할당하는 상황을 생각해보자.

 

각 변수를 변개로 인식하려면 500개의 변수 공간을 확보하는 것은 불가피하다. 

숫자 5를 매번 변수공간에 할당하려고 하면 숫자형은 8바이트이니, 4000(500*8) 바이트를 써야 할 것이다.

그 대신, 5를 별도의 공간에 한번만 저장하고 해당 주소만 입력하면,

예를 들어 주소공간이 2바이트라고 한다면 1008(500 * 2 + 8) 바이트만 이용하면 된다. 

이러한 이유들로 데이터 영역과 변수 영역을 분리하면 중복된 데이터에 대한 처리 효율이 높아진다.