프로세스 주소 공간
프로세스 주소 공간
프로세스는 운영체제가 자원을 할당하는 단위이다. 프로세스는 운영체제로부터 메모리를 할당받고 관리하게 된다.
런타임 환경에서의 프로세스의 메모리 구조의 모습을 프로세스 이미지 혹은 프로세스 주소공간이라고 칭한다.
프로세스의 주소공간은 대략적으로 다음과 같이 구성된다.
코드, 데이터, 힙, 스택 영역으로 구성된다.
-
스택 영역
- 함수나 메소드의
지역변수(local variable)과매개변수(parameter)가 저장되는 공간이다. 함수나 메소드가 호출될 때 마다스택 프레임(stack frame)이 쌓인다. - 힘수의 호출이 완료되면 할당된 지역변수, 매개변수, 스텍 프레임은 소멸된다.
- 메모리의 높은 주소에서 낮은 주소의 방향으로 할당된다.
- 재귀 함수가 너무 깊게 호출되거나 함수가 지역변수를 너무 많이 가지고 있어 stack 영역을 초과하면 stack overflow 에러가 발생한다.
- 함수나 메소드의
-
힙 영역
런타임에 크기가 결정되는 영역이다.- 사용자에 의해 공간이 동적으로 할당 및 해제된다.
- 주로
참조형 데이터 (ex. 클래스)등의 데이터가 할당된다. - 메모리의 낮은 주소에서 높은 주소의 방향으로 할당된다.
-
데이터 영역
- 프로그램에서 사용하는
전역 변수나 Static 변수등을 초기화 하는 영역이다. - 어떤 프로그램에 전역/static 변수를 참조하는 코드가 존재한다면, 해당 변수들은 컴파일 된 후에 data 영역을 참조하게 되며 실행 환경에서 자유롭게 접근하여 수정 및 변경이 가능하다.
- 프로그램의 시작과 함께 할당되며, 프로그램이 종료되면 소멸한다.
- 프로그램에서 사용하는
-
BSS 영역
- 데이터 영역과 마찬가지로 초기화 시키는 영역이지만, 메모리 상 공간만 잡아 놓고 실제로 값을 초기화시키진 않는다.
- 어느정도의 공간의 크기를 저장할 것이라는 정보를 저장하며 이 후 런타임 시 가상메모리에 링크된 후 세그먼트로 변환될 때 영역이 실제 확보된다고 한다.
- 데이터 영역은 초기에 사용할 메모리를 확보하는 반면, bss영역에서는 런타임 후에야 메모리 영역이 확보되므로, 메모리 사용의 관점에서 bss영역의 사용은 효율적이다.
-
Text (Code) 영역:
- 우리가 작성된 코드가 저장된 영역이다.
- 우리의 코드가 전처리 - 컴파일 - 어셈블 - 링크 의 과정을 겪어 CPU가 실행할 수 있는 기계어 코드로 변환된 코드가 저장되어 있는 공간이다.
- 이 공간은 프로그램 실행 도중 변경 및 수정이 불가능하다.
코드 예시
왼쪽의 코드와 오른쪽의 주소공간을 비교해보면 각 영역에 저장되는 프로그램의 구성 요소를 자세히 살펴볼 수 있다.
가장 아래에, 우리가 작성된 코드가 있다. (실제로는 기계어 코드가 담긴다,)
그 위로, 데이터영역이다. 전역변수이면서 선언과 동시에 값이 할당된 변수인 bufsize 가 담긴다.
그 위로, bss영역이다. 전역변수이지만 할당할 필요가 없는 변수, 여기서는 배열이 선언되어 있다. 이 배열에 대한 메모리 공간은 살제 런타임에서 쓰일 때, 그제서야 실제 메모리 영역이 확보된다. 메모리 할당을 실제 쓰이기 전까지 미룰 수 있으므로 시스템 입장에서 효율적이다라고 할 수 있다.
이후 힙 영역이 등장한다. 여기서는 malloc으로 동적으로 할당된 100바이트의 메모리 공간이 힙 영역에 담겨 있고 낮은 주소에서 높은 주소로 할당된다
스택 영역에는 위에서 아래로 메인함수, 이후 호출되는 f1에 대한 stack frame이 차곡차곡 쌓인다.
스택 영역과 힙 영역의 차이점
각 영역 공간의 크기
위 그림에서 볼 수 있듯이, 스택영역은 위에서 아래로, 힙영역은 아래에서 위로 메모리를 할당받는다.
두 영역은 모두, 런타임시 사용되는 메모리를 차곡차곡 쌓아가기 때문에, 런타임에서 프로그램이 너무 많은 양의 메모리 공간을 사용한다면 서로의 영역이 침범될 가능성이 있다.

위 그림은 Java에서의 Stack 영역과 Heap 영역을 나타낸다. 잘 살펴보면, Stack 영역에 등장하는 각각의 변수들은 Heap 영역에 위치한 실제 Object의 참조를 갖고 있는 것을 볼 수 있다. 즉, 실제 객체는 Heap 영역에서 관리되기 때문에 Stack 영역의 크기는 생각보다 클 필요가 없다는 것을 알 수 있다.
실제로, 자바에서 할당할 수 있는 스택영역의 최대 크기는 8MB에 불과하다고 한다. 반면 힙 영역은 8G도 가능하다.
더욱이 Stack 영역은 생성과 동시에 크기가 정해진다. 즉, 크기가 한 번 정해지면 바뀌지 않기 때문에, Heap 영역과 상관 없이 크기의 제한을 갖는다.
즉, 우리가 자주 볼 수 있는 Stack Overflow 같은 문제는, 힙 영역을 침범해서가 아니라 정해진 Stack 영역의 크기를 초과해서 발생한 문제라고 볼 수 있다.
메모리 접근과 관리
- 스택
-
매우 빠른 액세스
-
변수를 명시 적으로 할당 해제 할 필요가 없다.
- 공간은 CPU에 의해 효율적으로 관리되고 메모리는 파편화(fragmentation)되지 않는다
- 변수의 크기를 조정할 수 없다. 한번 할당되면 끝
-
-
힙
- (상대적으로) 느린 액세스
- 변수는 전역적으로 액세스 가능하다(ex. 멀티스레딩)
-
효율적인 공간 사용을 보장하지 못하면 메모리 블록이 할당 된 후 시간이 지남에 따라 메모리가 조각화되어 해제 될 수 있다.
- 메모리를 프로그래머가 관리해야한다(변수를 할당하고 해제하는 책임)
Reference
- https://junghyun100.github.io/%ED%9E%99-%EC%8A%A4%ED%83%9D%EC%B0%A8%EC%9D%B4%EC%A0%90/
- https://velog.io/@klm03025/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EC%A3%BC%EC%86%8C-%EA%B3%B5%EA%B0%84
- https://shinluckyarchive.tistory.com/159
댓글남기기