[CS] 메모리 구조 / 프로그램 / 프로세스 / 스레드
Program / Process / Thread
Program
: 컴퓨터에서 특정 작업을 위해 실행할 수 있는 정적인 상태의 코드 파일.
- 운영체제에서 아직 프로그램에게 독립적인 메모리 공간을 제공하지 않은 상태. 모든 프로그램은 실행되기 위해 운영체제로부터 메모리 공간을 할당 받아야 한다.
- 일반적인 예로
Windows
의 .exe
macOS
의 .dmg
파일 등이 존재.
Process
: 프로그램이 실행되어 돌아가는 상태, 컴퓨터에서 실행되고 있는 동적인 상태의 프로그램. 프로그램의 인스턴스. 운영체제로부터 독립된 메모리 공간을 할당 받은 상태.
Thread
: 프로세스가 할당 받은 자원을 이용하는 실행 단위, 프로세스의 특정한 수행 경로, 프로세스 내에서 실행되는 여러 흐름의 단위. 한개의 프로세스는 하나 이상의 스레드를 포함할 수 있다.
- 프로세스가 할당받은 메모리 영역에서
stack
형식으로 할당된 메모리 영역은 따로 할당받고, code
data
heap
메모리 영역은 서로 공유한다. 각각의 스레드는 별도의 stack
을 가지고 있지만 heap
영역은 서로 공유한다.
- 운영체제 입장에서 작업의 최소 단위는 스레드가 아닌 프로세스이며,
CPU
입장에서 작업의 최소단위는 스레드이다. 멀티 스레딩이 스케쥴링은 운영체제가 처리해 주지 않기 때문에 개발자가 직접 동기화 문제에 대응할 수 있어야함.
Multithreading 장점
heap
영역에서 공유하고 있는 메모리 자원만큼 메모리 공간을 아낄 수 있다.
heap
영역에서 자원을 공유하므로 스레드간 통신의 필요가 없으므로 응답시간이 빠름.
Multithreading 단점
- 프로세스가 예상치 못하게 종료되면 다른 프로세스에게 영향을 주지 않지만 스레드는 공유하고 있는 자원에 영향을 줘 망쳐버리면 프로세스가 종료될 수 있다.
- 자원을 공유하기 때문에 동기화 문제가 발생.
- 스레드
A
B
가 동시에 자원에 접근한다면 문제 발생.
프로세스 메모리 구조
메모리 구조
Text(code)
: 프로그램의 코드가 저장됨, CPU
는 code
영역에서 명령어를 가져와 처리함. 읽기만 가능한 메모리 영역이기 때문에 데이터를 저장하려고 시도하면 충돌을 일으킴. 컴파일시 크기가 결정됨.
Data
: 전역변수, 정적변수, 배열, 구조체등이 저장된다. 읽기, 쓰기가 가능한 메모리 영역이며, 프로그램이 시작될때 할당되고 프로그램이 종료되면 소멸한다. 컴파일시 크기가 결정됨.
BSS
: 초기화 하지 않은 전역변수, 정적변수가 저장됨. 컴파일시 크기가 결정됨.
Unused memory
: stack
과 heap
영역은 같은 메모리 공간을 공유한다. heap
이 메모리의 낮은 주소부터 할당되며 stack
은 높은 주소부터 할당된다. 각 영역이 상대 공간을 침범하는 일이 발생하는데 이게 그 유명한 stack overflow
heap overflow
이다.
Stack
: 함수 인자값, 함수 내의 지역변수, 매개변수, 리턴 값 등 일시적으로 사용후 사라지는 데이터를 저장한다. LIFO
방식을 따르기 때문에 메모리의 높은 주소에서 낮은 주소의 방향으로 데이터가 할당된다. 스택은 컴파일 타임에 의해 크기가 결정되며 재귀함수가 너무 깊어지거나 지역변수가 너무 많은등 스택 영역을 초과하게 되면 stack overflow
가 발생한다. stack
사이즈는 각 프로세스마다 할당되지만 프로세스가 메모리에 로드될 때 stack
사이즈가 고정되어 있어 런타임 시 stack
사이즈를 바꿀 수 없다.
Heap
: code
, data
, stack
영역과는 다르게 런타임에 따라 크기가 결정된다. c의 malloc함수를 이용해 heap영역의 메모리를 사용하거나 포인터변수를 할당하면 포인터가 가리키는 heap영역의 임의의 공간으로부터 원하는 크기만큼 할당해서 사용한다. 스택 메모리보다 할당할 수 있는 메모리 공간이 많지만, 포인터로 메모리의 영역을 접근해야 하기 때문에 속도가 느리다.