메모리는 말그대로 저장소다. 뭔가를 하려면 어떤 데이터를 어떻게 처리하라고 한다. 즉 데이터와 처리명령 두가지가 필요하다.
그래서 메모리도 두 영역으로 나뉘어 있다. Program / Data 부분이 나뉜다.
메모리는 당연히 빠를수록 비싸다. 그래서 빠르고 비싼 메모리는 용량이 작다. 반대로 느리면서도 싼 메모리는 용량이 크다. 아주 쉽게 생각할 것은 HDD와 SSD의 차이를 생각해보면 된다.
그래서 위와 같은 그림이 나온다. 레지스터와 캐시는 CPU 내부에 존재한다. 그만큼 작고 빠르다. Cache는 SRam과 같다. Memory는 Dram이다. 흔히 RAM 이라고 부른다. 8GB DDR4 램 사면 이거다. Disk는 하드디스크 그거다.
보통 레지스터, 캐시, 메모리를 주 기억장치, 디스크를 보조 기억장치라고 부른다. 주 기억장치는 보조보다는 빠르나 전원을 끄면 데이터가 날아간다.(휘발성)
메모리는 다음 그림과 같이 공간을 나누어 관리한다.
그림에 따라 low address와 high address가 반대가 되어 스택이 쌓이는 구조로 보이기도 한다. 그러나 중요한 점은 메모리는 사용용도에 따라 구역을 나누어 관리하고 순서가 있다는 점이다.
프로그램 코드가 저장되는 영역이다. 따라서 코드영역이라고도 불린다. 물론 개발자가 작성한 소스코드는 아니고 기계어로 저장된다.
Read-Only Data다. CPU가 이 영역의 데이터를 fetch해서 실행한다.
전역변수, static 변수가 저장되는 공간이다.
초기화된 데이터는 data 영역에 저장되고, 초기화 되지 않은 데이터는 BSS(Block Stated Symbol)영역에 저장된다.
js의 var let const의 호이스팅 시 선언, 초기화, 할당에 관한 내용 중 초기화와 관련한 내용이지 않을까 싶다.
let과 const는 선언만 되며 초기화가 되지않아 메모리에 없다.
그런데 js는 전역 스코프 역시 객체다. 그럼 참조타입이라 heap에 저장될 것 같다.
실행 컨텍스트와 관련된 내용같은데 자세히 좀 더 알아보자
프로그램이 실행될 때만 생성되고 종료시 반환하는 영역이다.
흔히 참조타입이 저장된다. 이 영역에 저장하기 위해 new
키워드를 사용한다.
개발자가 임의로 만들 수 있는 영역이라 동적 할당영역이라고 부른다.
HEAP을 참조하는 영역이 없으면 GC가 돌면서 마킹을 통해 제거하는 영역이다.
지역변수, parameter, 리턴 값 등이 임시로 저장되었다가 사라지는 영역입니다.
원시 값 타입이 저장되는 공간입니다.
stack은 함수 호출 시 할당되며 함수 종료(return)시 제거됩니다.
엄격하게 LIFO가 지켜집니다. 이렇게 스택에 저장되는 호출정보를 stack frame이라고 합니다. 흔히 우리가 부르는 call stack은 stack frame과 연관이 있습니다.
- 개발자가 소스코드를 완성하여 컴파일 => 실행단계가 되면 코드는 TEXT에 올라간다.
- 프로그램이 실행되면 프로그램은 프로세스가 된다.(프로세스 == 실행중인 프로그램)
- 프로세스의 흐름에 따라 DATA영역에 전역과 static변수를 만든다.
- 코드의 흐름에따라 HEAP과 STACK영역을 움직이며 메모리를 사용한다.
- 프로그램이 종료되면 DATA영역을 반환한다.
너무 자주 봐왔고, 참조변수와 포인터에 관한 이야기다.
const arr = [1, 2, 3];
const foo = arr => {
arr[1] = 100;
arr = [4, 5, 6];
console.log(arr);
};
foo(arr);
console.log(arr);
어떻게 나올지는 항상 언제 물어봐도 메모리 그림을 그려 대답할 수 있도록 하자.