본문 바로가기
TIL

10. 11. 8일차 TIL 데이터 타입(심화1)

by 눈 새 2024. 10. 11.

오늘은 강의를 통해 JS의 데이터 타입과 특징에 대해 더욱 자세히 학습하였다.
또 변수가 메모리에 할당되는과정과 메모리에 대한 기본 지식을 습득하였다.


1. 데이터 타입의 종류 (기본형과 참조형)

JS에서 값의 타입은 크게 기본형(Primitive)과 참조형(Reference Type)으로 구분된다.

두 타입의 구분 기준은 값의 저장 방식과, 변성의 여부라고 한다.

 

1) 복제의 방식

  • 기본형 : 값이 담긴 주소값을 바로 복제
  • 참조형 : 값이 담긴 주소값들로 이루어진 묶음을 가르키는 주소값을 복제

2) 불변성의 여부

  • 기본형 : 불변성을 띔 
  • 참조형 : 불변성을 띄지 않음. 


2. 메모리와 데이터에 관한 배경지식

1) 메모리와 데이터

  • 비트(bit)
    • 컴퓨터가 이해할 수 있는 가장 작은 단위
    • 0과 1을 가지고 있는 메모리를 구성하기 위한작은 조각
    • 비트가 모여서 우리가 흔히 듣는 메모리가 만들어진다.
  • 바이트(byte)
    • 0과 1만 표현하는 비트를 모두 찾는 것이 부담되어 묶은 것
    • 1byte = 8bit
  • 메모리(Memory)
    • byte 단위로 구성
    • 모든 데이터는 byte단위의 식별자인 메모리 주소값을 통해서 서로 구분된다.
  • Java, C와 다른 JS의 메모리 관리 방식 (feat.정수형)

→ java 또는 c언어가 초기에 등장했을 때 숫자 데이터 타입은 크기에 따라 다양하게 지정해줘야 할 만큼 개발자가 handling할 요소들이 너무 많았다고 한다. 하지만 JS에서는 이런 부분에서 상당히 편히다. (메모리 이슈까지 고민하지 않아도 됨)

  • 식별자, 변수
    • var testValue = 3
    • 변수 = 데이터
    • 식별자 = 변수명

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

1) 할당 과정 예시

예시를 보고 아래의 표를 작성

 

(5002와 5003번에 다른 데이터가 있다고 가정)

변수영역 주소 ... 1002 1003 1004 1005 ...
데이터 ... str / @5004       ...
데이터 영역 주소 ... 5002 5003 5004 5005 ...
데이터 ... data_01 data_02 test   ...
  • 값을 바로 변수에 대입하지 않는 이유 ( = 무조건 새로 만드는 이유)
    • 자유로운 데이터 변환을 하기 위함이다.

이미 입력한 문자열이 길어진다면?

숫자는 항상 8byte로 고정이지만, 문자는 고정이 아니다. (영문 1btye, 한글 2btye)

그래서 이미 1003주소에 할당된 데이터를 변환하려할 때 더 큰 데이터를 저장하려 한다면

1004 주소 이후부터 저장되어 있는 모든 데이터를 오른쪽으로 싹 다 미루는 일이 생긴다.

즉, 자유로운 데이터 변환이 불가능하다는 것을 의미한다.

  • 메모리의 효율적 관리

똑같은 데이터를 여러번 저장해야한다면?

1만개의 변수를 생성해서 모든 변수에 숫자 1을 할당하는 상황을 가정해보자.

모든 변수를 별개로 인식한다고 한다면, 1만개의 변수 공간을 확보해야 한다.

바로 대입하는 숫자형 데이터는 8btye가 고정이므로 8만 btye가 필요한 셈이다.

하지만, 변수 영역에 별도로 저장하는 경우를 생각해보면

변수 영역 약 2만 btye (2btye x 10,000) + 데이터 영역 8btye (8btye x 1)이므로

총 20,800 btye를 사용하게 된다.


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

1) 메모리를 기준으로 다시 한번 생각해보는 두 가지 주요 개념

  • 변수 vs 상수
    • 변수 : 변수 영역 메모리를 변경할 수 있다.
    • 상수 : 변수 영역 메모리를 변경할 수 없다.
  • 불변하다 vs 불변하지 않다
    • 불변하다 : 데이터 영역 메모리를 변경할 수 없다
    • 불변하지 않다 : 데이터 영역 메모리를 변경할 수 있다.

데이터 영역의 데이터가 변경된 경우 (더 이상 사용하지 않게 된 경우)

가비지컬렉터의 수거 대상이 되어 메모리가 관리된다.

 

2) 불변값과 불변성 (with 기본형 데이터)

그렇다면 데이터적 관점에서 a라는 변수가 abc에서 abcdef가 되는 과정을 통해 불변성을 유추해보자.

'abc'라는 값이 데이터영역의 @5002라는 주소에 들어갔다고 가정하면,

var a = 'abc' 일 때, 'def'라는 값은 @5002라는 주소에 추가되지 않았다.

@5003에 별도로 'abcdef'라는 값이 생기고 a라는 변수는 @5002 → @5003로 교체된다.

즉, 주소가 교체되었을 뿐 데이터의 값이 변하지 않았기 때문에 변수 a는 불변하다라고 말할 수 있다.

이 때, @5002는 더 이상 사용되지 않기 때문에 가비지컬렉터의 수거 대상이 됩니다. a = a + 'def';

 

3) 가변값과 가변성 (with 참조형 데이터)

  • 참조형 데이터의 변수 할당 과정

예시를 보고 아래의 표를 작성

 

변수 영역 주소 1001 1002 1003 1004 ...
데이터 obj1 / @7103~       ...
데이터 영역 주소 5001 5002 5003 5004 ...
데이터 1 'bbb'     ...

 

객체의
변수 영역
주소 7103 7104 7105 7106 ...
데이터 a / @5001 b / @5002     ...
  • 기본형 데이터의 변수 할당 과정과 차이점
    • 객체의 변수(property) 영역이 별도로 존재한다.
  • 참조형 데이터가 불변하지 않다(가변하다)라고 하는 이유

a의 데이터를 2로 변경

변수 영역 주소 1001 1002 1003 1004 ...
데이터 obj1 / @7103~       ...
데이터 영역 주소 5001 5002 5003 5004 ...
데이터 1 'bbb' 2   ...
객체의
변수 영역
주소 7103 7104 7105 7106 ...
데이터 a / @5003 b / @5002     ...

이후 @5001에 들어있는 데이터 1은 가비지컬렉터의 수거 대상이 될 것이다.

  • 중첩객체의 할당

* 중첩객체란?

객체 안에 또 다른 객체가 들어가는 것을 의미한다.

객체는 배열, 함수, 등을 모두 포함하는 상위개념이기 때문에

배열을 포함하는 객체도 중첩객체라고 할 수 있다.

변수 영역 주소 1001 1002 1003 1004 ...
데이터 ojb / @7103~       ...
데이터 영역 주소 5001 5002 5003 5004 ...
데이터 3 4 5   ...
객체의 
변수 영역
주소 7103 7104 ...
데이터 x / @8104 arr / @8104~ ...
arr를 위한
별도 저장 영역
주소 8104 8105 8106 ...
데이터 0 / @5001 1 / @5002 2 / @5003 ...
  • 참조 카운트가 0인 메모리 주소의 처리

* 참조카운트란?

객체를 참조하는 변수나 다른 객체의 수를 나타내는 값이다.

참조 카운트가 0인 객체는 더 이상 사용되지 않으므로 가비지 컬렉터에 의해 메모리에서 제거된다.

* 가비지컬렉터(GC, Garbage Collector)란?

더 이상 사용되지 않는 객체를 자동으로 메모리에서 제거하는 역할을 수행한다.

JS는 가비지 컬렉션을 수행함으로써 개발자가 명시적으로 메모리를 관리하지 않아도 되도록 지원한다.

가비지컬렉터는 JS 엔진에서 내부적으로 수행되며 개발자는 가비지 컬렉션에 대한 직접적인 제어를 할 수 없다.

 

4) 변수 복사의 비교

사진을 보고 아래의 표를 작성

변수 영역 주소 1001 1002 1003 1004 1005 ...
데이터 a / @5001 obj2 / @7103~ b / @5001 obj3 / @7103~   ...
데이터 영역 주소 5001 5002 5003 5004 5005 ...
데이터 10 'ddd'       ...
객체의
변수 영역
주소 7103 7104 ...
데이터 c / @5001 d / @5002  

 

5) 복사 이후 값 변경1 (객체의 프로퍼티 변경)

객체의 프로퍼티 변경

변수 영역 주소 1001 1002 1003 1004 1005 ...
데이터 a / @5001 obj2 / @7103~ b / @5003 obj3 / @7103~   ...
데이터 영역 주소 5001 5002 5003 5004 5005 ...
데이터 10 'ddd' 15 20   ...
객체의
변수 영역
주소 7103 7104 ...
데이터 c / @5004 d / @5002 ...
  • 기본형
    • 숫자 15라는 값을 데이터 영역에서 검색 후 없다면 생성
    • 검색한 결과 주소 또는 생성한 주소르 ㄹ변수 영역 b에 갈아끼움
    • a와 b는 서로 다른 데이터 영역의 주소를 바라보고 있기 때문에 영향이 없다.
  • 참조형
    • 숫자 20이라는 값을 데이터 영역에서 검색 후 없다면 생성
    • 검색한 결과주소 또는 생성한 주소 obj3에게 지정되어 있는 별도 영역(@7103~)에 갈아끼움
    • obj2도 똑같은 주소를 바라보고 있기 때문에 obj2까지 변경 됨.
    • 결국 원하지 않았던 현상이 발생하게 됨.

6) 복사 이후 값 변경2 (객체 자체를 변경)

객체 자체를 변경

변수 영역 주소 1001 1002 1003 1004 1005 ...
데이터 a / @5001 obj2 / @7103~ b / @5003 obj3 / @8204~   ...
데이터 영역 주소 5001 5002 5003 5004 5005 ...
데이터 10 'ddd' 15 20 'aaa' ...
객체의 
변수 영역1
주소 7103 7104 ...
데이터 c / @5001 d / @5002 ...

 

객체의
변수 영역2
주소 8204 8205 ...
데이터 c / @5004 d / @5005 ...

 

→ obj3 변수는 참조형 데이터이고, 참조형 데이터의 값을 변경한 것임에도 불구하고,

    이전 케이스와는 다르게 obj2와 바라보는 데이터 메모리 영역의 값이 달라진 것을 알 수 있다.

즉, 참조형 데이터가 "가변값"이라고 할 때의 "가변"은 참조형 데이터 자체를 변경할 경우가 아닌,

그 내부의 프로퍼티를 변경할 때 성립한다고 할 수 있을 것이다.


★ 08일차 소감

강의를 보며 데이터 할당이 어떻게 되는지 표를 작성하였다. 머리로는 이해했다고 생각했는데 잘 되지 않고 헷갈리는 부분이 많아 5~6번씩 강의를 돌려본 것 같다. 오늘 마저 학습하지 못한 부분은 내일 보충하여 진도를 맞출 생각이다.. 이제 조금 머리를 깨우고 있다는 생각이 드는 강의였다.