프로세스 메모리 구조., 힙 스택
프로세스 메모리 구조와 힙스택은 따로 정리 할 필요성을 느끼지 못하여서 하나의 통합본으로 정리 하도록 하겠다.
일단 프로세스의 메모리구조, 메모리와 프로세스의 상호작용 방식, 정적 메모리 레이아웃과 동적 메모리 레이아웃을
다루게 되는데 여기서 힙 스택에서도 사용되는 메모리 로직을 따르게 된다 .
프로세스 메모리 레이아웃
일반적으로 프로세스는 실행중인 프로그램을 뜻하는데 여기서 각 프로세스들은 고유의 아이디를 할당 받게 되고
이를 통해 운영체제와 상호적으로 데이터의 통신이나 여러 작업들을 할 수 있게 된다. 이때 새로운 프로세스를
만들거나, 로딩하는것은 운영체제 고유한 역할이다.
linux계열에서 프로세스를 실행하는것은 execve, execle 와 같은 함수를 호출하여 프로세스를 새로 실행하게 되는데
이때 우리는 하나의 프로세스에서는 하나의 프로그램 밖에 사용하지 못한다. 이유는 윗줄에서 설명 했던 이유 이기도 하고
따라서 우리는 운영체제에서 새로운 프로세스를 만들어주세요, 라고 하는 fork와 같은 녀석들을 이용하게 되는 이유이다.
이때 프로세스에게 신호를 보내는데 sigkill sigquit 등 여러 시그널이 존재하고 이는 인터넷을 찾아보면 너무 많은 것을 알 수 있다.
이제 프로세스를 생성할때 만들어 지는 것들에 대해서 집중을 할 필요성을 느낄 수 있다. 첫번째로
운영체제는 프로세스를 생성할때 정적으로 할당된 크기많큼 메모리에 적재 하는 과정을 거치고 미리 정의된 메모리 레이아웃을
적용 하게 된다. 이때 레이아웃의 각 부분을 세그먼트 라고 부르고 여기에 해당하는 내용은
BSS, DS, CS(Text Seg) SS, HS 와 같이 이름을 붙여서 사용한다
BSS 의 경우 심벌 세그먼트로 초기화 되지 않은 워드 그냥 초기화되지 않은 전역 변수를 위한 공간들 이라고 보면 이해하기 편할 듯 하다 .
DS 0이 아닌 값으로 초기화된 전역변수가 들어가는 공간
CS 우리가 작성해둔 코드가 파싱되어 처리되어 있는 공간이라고 보면 이해하기 편하다.
이때 전장에서 배웠던 오브젝트의 내용들이 이공간에 저장되어 있고 이 공간을 해석하면서 처리하는데 사용된다.
SS
스택은 프로세스의 동적 메모리에서 매우 중요한 부분으로 거의 모든 아키텍쳐에서 사용되는 공간이다.
함수를 호출할 때 마다 스택프레임이 호출한 새 엔트리가 스택 세그먼트 위에 놓이고 이 아래에서 동작이 진행되는 로직으로
구성되어 있음.
HS
힙세그먼트는 일반적으로 동적할당된 메모리들이 저장되는 장소 이다.
스택은 결국 선입 후출 구조로 이루워 져있으며 이는 프링글스를 생각하면 이해하기 편하다.
함수를 호출하고 호출된 함수에서 다른 함수를 호출하여 1 -> 2 -> 3의 구조로 돌아가는 로직이 있다고 한다면 이는
결국 1 이 들어온 다음 2가 들어오고 3이 들어오는 로직과 다름이 없다. 이때 이 로직이 오버플로 나거나 충돌 한다면
예상치 못한 결과를 리턴하는 로직이 발생하는 이유 이기도 하다.
힙과 스택의 가장 큰 차이는 스택의 경우 이미 프로세스에서 어디서 어떻게 동작할지에 대해 알고 있다는 것과,
모른다는 점이 가장 큰 차이가 아닐까 싶다. 여기서 HS의 경우 우리가 동적으로 할당 하는 크기를 가지게 되며
할당 전에 사용한다거나 할 수 없다,. 또한 힙과 스택의 가장 큰 차이로는 힙영역이 없다고 프로그램이 동작하지 않거나
하지는 않지만 스택세그먼트가 없어진다면 프로그램이 동작하지 않게된다. 왜냐하면 절차적으로 동작을 진행하는 컴퓨터에서
이 스택 프레임에 데이터를 쌓아놓고 처리하는 로직으로 동작하게 될 것인데 이때 데이터들이 저장되고 처리되는 로직들이 없기
때문에 컴퓨터에서 이해할 수 없기 때문이 아닐까 싶다.
그렇다면 힙이 필요가 없는 것 일 까? 그것은 또 아니다. 큰 용량의 객체를 저장하거나 데이터를 변경할때 스택 영역의 경우
다른 주소들과 곂쳐 순차적으로 처리될것 인데 이 범위를 넘어가게 되거나 충돌하게 될 수 있어서
위와 같은 경우에서 우리는 힙을 사용하게 된다. 하지만 무분별한 동적 할당을 하게 되면 지속적으로 할당, 해제 하는 부분을
반복해야 하고 이를 통해서 데이터의 누수와 같은 문제점에 직면 할 수 있다.