메모리와 데이터 타입

Jin Baek·2021년 12월 28일
0

javaScript

목록 보기
2/2
post-thumbnail

잘못된 부분이 있으면 지적 부탁드립니다.


프로그램 실행 플로우

컴퓨터가 프로그램을 실행하는 과정을 간단히 해보면 네단계를 거친다

  1. CPU가 코드 실행에 필요한 데이터들을 하드디스크에서 가져온다
  2. 가져온 데이터를 RAM 메모리에 올린다
  3. CPU가 연산작업을 하여 결과물을 받아온다
  4. 사용자에게 결과물을 반환한다

메모리

위의 프로그램 실행 플로우에서 CPU가 데이터를 RAM 메모리에 올려줄때
스코프와 변수 선언, 참조 등 다양한일이 벌어진다

메모리는 크게 4가지 영역으로 구분할수 있다

  1. 코드 영역
  • 실행할 프로그램의 코드가 저장되는 영역이다
  • 저장된 코드를 CPU가 한줄씩 처리한다
  1. 데이터 영역
  • 프로그램의 전역 변수와 정적 변수가 저장되는 영역이다.
  • 프로그램의 시작과 동시에 할당이 되고, 프로그램이 종료되면 제거된다
  1. 힙 영역
  • 사용자가 직접 관리할 수 있고, 관리 해야만 하는 영역이다
  • 객체를 생성하는 경우 이 영역에 할당이 되고
    해당 객체가 더이상 참조되지 않으면 해제가 된다
  1. 스택 영역
  • 함수의 호출과 관련있는 데이터가 저장되는 영역이다
  • 함수가 호출되면 이 영역에 할당되고 호출이 끝나면(리턴되면) 소멸한다
    이를 자바바스크립트에선 excution context 또는 call stack이라 부른다

데이터 타입

자바스크립트에서의 자료형들은 크게 원시 타입참조 타입으로 구분이 가능하다. 자바스크립트는 원시값을 제외한 모든것이 참조형 객체이다
원시값은 프로그래밍 언어에서 미리 사용할 수 있도록 만들어준 데이터인데
String, Number, Boolean, Undefined, Symbol, Bigint 그리고 Null값이 원시값에 해당하고 이 외의 모든 데이터들은 다 객체타입으로 사용된다

원시타입과 객체타입의 가장 큰 차이점은, 값의 변경이 가능한지대한 여부이다 이를 가변성(mutable)불변성(immutable)이라 부른다

원시값(primitive value)들은 자바스크립트에서 제공해준 값들이 조합(숫자, 문자열, undefined 등)이므로 메모리의 공간을 얼마나 사용할지가 사전에 정의가 가능하다. 하지만 객체 리터럴의 경우, 동적으로 확장이 가능해서 메모리상에 얼만큼 할당해주어야 하는지 알수가 없다.
따라서 자바스크립트는 원시값과 객체를 다른 방식으로 관리한다

원시값

원시 값의 특징은 immutable이다. 이는 원시값이 자바스크립트가 실행될때 제공하는 원시 값 데이터를 활용하기때문이다. 어떤 원시값을 변수에 할당하면, 변수에는 실제 값이 복사되어 저장되고 다른 변수가 원시값을
갖고 있는 변수를 값으로 할당하면, 언본의 원시값이 복사되어 전달된다.

title = 'deepDive 처럼 이미 선언되어있는 변수에 새로운 원시값을 할당할 경우(재할당), 자바스크립트는 새로운 메모리 공간에 새로 할당되는 값을 입력하고, 기존에 사용하던 변수명이 이를 가리키게 한다. 이때 이전에 할당되어진 값은 가리키고 있는 변수가 하나도 없으므로 가비지 컬렉터에의해 해제가 된다.

문자열

불변성

위의 title = 'deepDive처럼 문자열은 부분 수정이 안되는 불변성을 갖고있어서 변경이 필요한 경우 재할당을 해야한다

let str = 'abcd';
console.log(str[3]) // d
str[3] = 'a'; // 부분 수정을 시도하지만
console.log(str) // 'abcd' 변하지 않는다

유사 배열객체

자바스크립트의 문자열은 특이하게도 문자열이면서 동시에 유사 배열객체이기에 length 메소드도 활용이 가능 하다. 가능한 이유는 문자열 데이터 타입에 배열 메소드를 활용하게되면 자바스크립트가 자동으로 String 객체 래퍼로 문자열을 감싸주기 때문이다. 따라서 문자열은 유사 배열 객체이면서
이터러블(순회가 가능)함으로 배열과 유사하게 각 문자에 접근 할수 있다


ler str = 'hi';
console.log(str[0]) // 이때 String 객체래퍼로 문자열이 감싸진다
	 // String(str) === {0: 'h', 1:'i'} 가 되고
	 // String(str)[0] === 'h'가 된다

참조값

원시 값은 이미 제공되는 primitive data들을 활용해서 immutable한 특징을 갖고 있다. 반면 참조값은 객체 값이고 프로퍼티의 개수가 정해져 있지 않으며 동적으로 추가되고 삭제될수 있다. 그렇기때문에 객체는 원시값과 같이 메모리 공간의 크기를 사전에 정해둘수 없고 동적으로 관리된다

객체와 mutability

자바스크립트는 객체를 생성하게 될때, 힙 메모리에 객체 인스턴스를 생성하고, 이
인스턴스가 존재하는 위치를 스택 메모리에 기록하여 사용한다.
이러한 특징때문에 객체를 변수에 할당하게 되는 경우, 변수는 해당 객체가 메모리상에 존재하는 주소를 참조하게 된다.

마무리

변수를 선언하고 사용할때 메모리에서 어떤식으로 할당이 되는지와 문자열의 불변성은 평소에 전혀 생각하지 못했던 부분이였다.

참고

팀 러버덕 리더 훈님 자료
모던 자바스크립트 deep dive 11장
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management#garbage_collection

0개의 댓글