운영체제의 메모리 구조는 유저 영역, 커널 영역 두 가지로 분리된다.
편리한 관리를 위해, 일반 프로그램의 실행을 위한 메모리 공간과 운영체제의 실행을 위한 메모리 공간으로 분리시켰다.
유저 영역은 다시 스택, 힙, 데이터, 코드 영역으로 나뉘며, 유저 영역을 제외한 영역을 커널 영역이라고 한다.
커널 영역
커널 영역에는 커널(kernel)이 위치하고 있으며, 이 커널은 컴퓨터 운영체제의 핵심이라고 할 수 있다.
커널은 시스템의 모든 것을 완전히 통제하기 때문에 사용자(유저 모드)가 직접 접근할 수 없으며, 접근 시 system call을 통한 커널 모드로의 전환이 필요하다.
유저 영역
유저 영역은 스택, 힙, 데이터, 코드 영역으로 나뉜다. 엄밀히 말하자면 하나의 프로세스를 묶어 놓은 세그먼트(segment)가 존재하는데, 이 세그먼트가 스택, 힙, 데이터, 코드 영역으로 이루어져 있는 것이다.
즉, 프로세스마다 스택, 힙, 데이터, 코드 영역이 존재한다.
스택 영역
함수(프러시져) 내에서 지역 변수와 매개변수가 저장되는 영역이다.
스택 영역이 처음 생성될 때(함수가 실행될 때) 필요한 크기만큼 만들어지고, 데이터를 저장해 나간다.
함수가 끝나게 되면 스택 영역은 소멸된다.
힙 영역
동적으로 메모리를 할당하여 사용하는 공간이며, 참조형의 데이터 값이 저장된다.
동적 할당을 하게 되면 메모리 사용 후 동적 할당 해제가 필요한데, 만약 해제하지 않으면 메모리가 부족해져 메모리 누수(memory leak)가 발생할 수 있다.
데이터 영역
프로그램이 구동되는 동안 항상 접근이 가능한 변수가 저장된다.
초기화되지 않은 데이터가 저장되는 BSS, 초기화된 데이터가 저장되는 GVAR 두 가지 영역으로 나뉜다.
프로그램의 전역 변수와 정적 변수가 저장된다.
프로그램 시작과 함께 할당되고, 프로그램이 종료되면 소멸한다.
코드 영역
실행할 프로그램의 코드가 저장되는 영역이다.
CPU는 코드 영역에 저장된 명령을 하나씩 가져가서 처리한다.
프로그램이 시작되고 종료될 때까지 메모리에 계속 남아있는다.
스택 영역과 힙 영역의 장단점
스택 영역은 데이터 액세스가 빠르며, 변수를 사용자가 관리하지 않아도 된다. 또한 하나의 명령으로 메모리 조작과 어드레스 조작이 가능하고, 운영체제가 직접 메모리를 관리해주기 때문에 메모리 단편화에 대한 걱정이 없다는 장점이 있다.
하지만, 지역 변수만 저장되고 스택 크기에 제한이 있으며, 변수의 크기를 조정할 수 없다는 단점이 있다.
힙 영역은 변수를 전역적으로 액세스 할 수 있으며, 메모리 크기에 제한이 없다. 또한 객체의 개수나 크기를 알 수 없어도 사용 가능하다는 장점이 있다. 하지만, 상대적으로 데이터 액세스가 느리며, 메모리를 직접 관리해야 한다는 단점이 있다.
프로세스, 스레드에서의 스택
프로세스는 메모리에 올라갈 때 OS로부터 시스템 자원을 할당받는다. 이때 중요한 것은, OS는 프로세스마다 각각 독립된 메모리 영역을 할당한다. 위에서 공부한 스택, 힙, 데이터, 코드 영역을 할당해주는 것이다. 각각 독립된 메모리 영역을 할당해주므로 프로세스끼리는 서로 변수나 자료에 접근할 수 없다.
스레드는 메모리를 서로 공유할 수 있다. 프로세스가 할당받은 메모리 영역 내에서 스택 영역은 따로 할당받고, 힙, 데이터, 코드 영역의 메모리는 공유한다. 따라서 각각의 스레드는 별도의 스택을 가지고 있지만, 힙 메모리는 서로 읽고 쓸 수 있게 된다. 스레드는 메모리 영역을 공유하기 때문에 어떤 스레드 하나에서 오류가 발생하면 같은 프로세스 내의 다른 스레드에도 영향을 준다.