프로세스 주소 공간
Last updated
Last updated
프로그램
이 실행되면 프로세스 주소 공간
이 메모리
에 할당(생성)되고, 할당된 프로세스를 CPU가 실행시킴
프로세스가 메모리를 할당받을 때, 자신만의 방법으로 메모리를 관리하기 위한 공간을 프로세스 주소 공간
이라고 함
한정된 메모리를 효율적으로 사용하기 위해 스레드와 공유하는 공간을 가짐
함수(function)나 지역 변수(local variables) 저장(읽고 쓰기 가능)
호출된 함수의 수행을 마치고 복귀할 주소 및 데이터(지역변수, 매개변수, 리턴값 등)를 임시로 저장하는 공간
함수 호출과 함께 할당되며, 함수의 실행이 완료되면 소멸됨
자료구조 Stack과 같은 LIFO(Last In First Out) 방식으로 동작함
컴파일 타임
에 Stack 영역의 크기가 결정되기 때문에 무한정 할당 불가능(동적으로 할당 및 해제 불가능)
메모리의 높은 주소에서 낮은 주소의 방향으로 할당됨
재귀 함수가 반복해서 호출되거나 함수가 지역변수 메모리를 초과할 정도로 많이 가지고 있을 경우, stack overflow 발생
Stack 영역에 저장되는 변수들은 사실 Heap 영역에 위치한 실제 Object의 참조만 갖고 있음
프로그래머가 필요할 때마다 사용하는 메모리 영역
사용자에 의해 공간이 동적으로 할당되고 해제됨
런타임
에 할당해야 할 메모리의 크기가 결정됨
메모리의 낮은 주소에서 높은 주소의 방향으로 할당됨
자바에서는 객체가 Heap 영역에 생성되고 GC(Garbage Collection)에 의해 정리됨
전역 변수(global variables) 같은 데이터 저장(읽고 쓰기 기능)
전역 변수 또는 static 변수 등 프로그램이 사용하는 데이터를 저장하는 공간
전역 변수 또는 static 값을 참조한 코드가 있으면, 컴파일이 완료된 후에 Data 영역의 주소값을 참조함
프로그램의 시작과 함께 할당되며, 프로그램이 종료되면 소멸됨
전역 변수가 변경될 수 있기 때문에 Read-Write
로 되어 있음
초기화되지 않은 변수가 존재할 경우, BSS 영역에 저장됨
BSS 영역(Block Started by Symbol): 초기화 되지 않은 변수를 0으로 초기화하여 저장
Data 영역: 0이 아닌 다른 값으로 할당된 변수 저장
프로그램의 소스 코드 저장(읽기만 가능)
사용자가 작성한 프로그램 함수들의 코드가 CPU에서 수행할 수 있는 기계어 명령 형태로 변환되어 저장되는 공간
컴파일 타임에 결정됨
중간에 코드를 바꿀 수 없게(프로그램이 수정되지 않도록) Read-Only
로 되어 있음
최대한 데이터를 공유하여 메모리 사용량을 줄이기 위해 영역을 나눔
Code 영역
Code는 어느 시점에 참조하여도 Process 내부에서는 항상 같은 내용이기 때문에 따로 관리하여 공유함
프로그램의 코드는 프로그램이 컴파일되고 나서는 바뀌지 않음(Read Only)
같은 프로그램을 실행시켜 여러 개의 프로세스가 실행되더라도 Code 부분은 항상 똑같은 내용을 가지게 됨
같은 프로그램의 프로세스일 경우, Code 부분을 공유하여 메모리 사용량을 줄일 수 잇음
Stack영역과 Data 영역
역할의 분배
스택 구조의 특성과 전역 변수의 활용을 위해 Stack과 Data를 분할함
Stack 영역을 통해 함수의 흐름을 관리하고, Data 영역(+BSS 영역)을 통해 전역변수와 static 변수 등을 관리함
한 프로세스가 여러 개의 스레드를 갖는 경우, 각각의 스레드는 자신만의 Stack 영역을 가지게 됨
스레드 내에서 수행되는 함수의 흐름을 각각 관리하기 위함
각각의 스레드는 Stack 영역을 갖긴 하지만, Data 영역은 공유함
각각의 스레드가 사용하기 위해 Data 영역의 동일한 내용을 공유함으로써, 똑같은 공간을 만들지 않고 메모리를 절약할 수 있음
속도
Stack은 CPU가 직접 관리하고 최적화하기 때문에 Heap 영역에 비해 접근 속도가 빠름
Stack은 이미 할당된 공간을 사용하고, Heap은 따로 할당하여 사용해야하기 때문에 Stack이 Heap 영역보다 할당 속도가 빠름
크기
Stack과 Heap 사이에는 미사용 공간이 존재하며, Stack과 Heap의 할당에 따라 크기가 줄어듦
처음부터 Stack과 Heap 공간이 할당되는 것이 아닌, 메모리 공간이 필요한 시기에 할당됨
Stack은 컴파일 타임에, Heap은 런타임에 크기가 결정됨
Stack은 생성과 동시에 크기가 정해지기 때문에 Heap 영역과 상관없이 크기의 제한을 가짐
앞서 Stack은 높은 주소부터, Heap은 낮은 주소부터 할당한다고 하였지만, 다른 아키텍쳐에는 반대인 경우도 있음
중요한 점은 각 영역을 교차시켜 배치함으로써 단순한 구현으로도 충분한 공간을 가짐
오버플로우
스택 오버플로우(Stack Overflow): 스택 영역 > 힙 영역 (스택 영역이 힙 영역을 침범하는 경우), 현재 스택 사이즈가 정해진 스택 영역 사이즈를 초과하는 경우
힙 오버플로우(Heap Overflow): 스택 영역 < 힙 영역 (힙 영역이 스택 영역을 침범하는 경우)
스레드가 생성되고 실행되는 동안 접근 가능한 메모리 영역으로, 프로세스 주소 공간 내에 형성됨
프로세스가 자원을 할당받지만, 스레드도 자신만의 자원을 가지고 있어야 함
스레드도 자신만의 주소 공간을 가짐
각 스레드가 갖고 있는 영역은 Stack 밖에 없음
나머지 공간(Code, Data, Heap)은 프로세스의 값을 함께 쓰고 있어 다른 스레드와 공유하고 있음
Data 영역에 있는 자원은 동시에 여러 스레드가 접근할 수 있음
때문에 스레드 컨텍스트 스위칭시 프로세스 컨텍스트 스위칭보다 빠르게 동작