728x90
하나의 프로그램(=instruction들의 집합, Process) 실행 시
- OS에 의해서
- 프로그램의 인스턴스인 process를 위해 마련되는 Memory의 구조는
- 다음의 영역으로 구분가능.
Kernel Space는 보통 메모리의 상위 주소에 할당되고,
User Space는 하위 주소에 할당됨.
이 문서에 다루는 Process의 User Space의 메모리 구조는 엄밀하게 애기하면,
- MMU를 사용하지 않는 경우 memory 구조, 또는
- MMU를 사용하는 경우엔 사용자에게 보여지는 virtual memory의 구조 에 해당하는 내용임
이 외에도 Kernel Space에 PCB(Process Control Block)이 생성됨.
아래 그림은 OS와 program, cpu가 사용하는 logical memory (or virtual memory)의 구조임.
위 그림에서 아래쪽이 address가 작은 숫자로 표시되는 하위주소영역이고, 위로 갈수록 상위주소영역임.
https://ds31x.tistory.com/152: Process 개념과 PCB 등을 확인.
https://dsaint31.me/mkdocs_site/CE/ch05/ch05_06_01_mmu/: MMU에 의한 실제 메모리 구성.
1. 사용자영역(User Space)에 Process 하나 당 생성되는 메모리 구조
1-1. 코드 영역(Code Area or Instructions, Code Segment): 정적할당영역
- 이름 그대로 실행할 프로그램의 코드(or Instructions)가 저장되는 메모리 공간.
- CPU는 코드 영역에 저장된 instruction(명령문)들을 하나씩 가져가서 실행을 함.
- CPU가 읽기 때문에 Text section 이라고도 함.
- 프로그래머(사용자)에게 보여지는 virtual memory에서 하위메모리 공간(주소가 낮은 수임)에 할당됨(von Neumann 컴퓨터).
- 프로그램 코드 내의 상수(위의 그림에서 Literals )들도 여기에 저장되며, OS가 할당에 필요한 메모리 크기를 적재하기 전에 알 수 있음.
- 위 그림에서 Literals (소스코드에서 고정된 상수값을 Literal이라고 부름) 영역까지 보통 code 영역으로 포함해서 애기하기도 함.
- Havard 구조의 컴퓨터에서는 별도의 memory 영역에 할당됨
(MMU를 사용하는 경우엔, 같은 physical memory 인 경우가 대부분).
읽기만 가능한 (Read-Only) 영역으로 해당 영역이 변경될 경우에는 segmentation fault가 발생함.
1-2. 데이터 영역 (Data Area or Static Data, Data Segment): 정적할당영역
- global variable(전역변수)와 static variable들이 할당됨.
- 이 영역에 할당되는 변수들은 프로그램의 시작 과 동시에 메모리 공간에 할당되어 프로그램 종료 시 할당해제됨.
- instructions 영역 (=code영역)과 마찬가지로 OS가 할당에 필요한 메모리 크기를 적재 시점에 알고 있음.
- instructions 영역 (=code영역) 위의 상위 메모리 공간에 할당됨.
초기값이 있는 영역을 data segment라고 하고 초기값이 없는 영역은 BSS라고 좀 더 세밀히 나누기도 함.
1-3. 힙 영역 (Heap Area or Dynamic Data, Heap Segment): 동적할당영역
- C언어를 포함한 다양한 프로그래밍 언어는 프로그래머가 원하는 시점에 변수를 할당하고 또 소멸하도록 지원함 :
Dynamic Memory Allocation - 이같이 프로그램 수행 중 동적으로 메모리에 할당되는 변수들이 저장되는 곳이 Heap.
- 이와 같은 방식을 메모리의 동적(dynamic) 할당이라고 하며,
생성과 소멸의 시점이 고정되어 있는 변수들(데이터 영역 또는 스택 영역에 할당)과는 달리,
할당하는 함수(malloc)가 호출될 때마다 매번 할당이 이뤄지지만
할당이 되면 전역변수와 마찬가지로 함수를 빠져나가도 소멸되지 않는 성격의 변수가 됨.- C언어에서는 malloc 함수와 free 함수 를 통해서 이러한 변수를 heap 영역에 할당하고 소멸할 수 있음.
- Java나 Python의 경우 Garbage Collection(GC)을 통해 관리되기 때문에
할당하고 나서는 해제는 GC에 의해 자동으로 이루어짐.
- OS가 사전에 필요한 메모리 크기를 알 수 없음 (크기가 run-time에 결정되며 적재하는 시점에 알 수 없음).
- run-time에 실제 사용량이 결정되며, 지나치게 많은 memory가 사용될 경우, process가 memory부족으로 비정상 종료된다:
Memory Leak - statics data영역 위의 상위 메모리 공간에 할당되며,
처음 할당된 변수가 메모리 주소로는 하위영역에 할당되고 후에 할당될수록 상위영역에 추가됨.
쌓는다는 의미(하위주소에서 상위주소로 쌓여간다는 의미)에서 쌓는다는 뜻의 Heap이라는 이름이 지어짐.
자료구조의 binary tree기반의 Heap과 관계 없음.
1-4. Stack 영역 (Stack Area or Stack Segment)
- Local variable (지역변수)와 Parameter(매개변수, argument가 값이 됨), 함수 복귀 주소 등이 할당됨.
- Stack Trace 정보가 저장됨.
- Strack Trace 는 Stack 영역에 저장된 함수 호출 정보를 의미하며, Exception이 발생시 디버깅에서 활용됨.
- 상위 memory address에서 하위 memory address순으로 메모리가 할당 (Heap의 역순)되며,
할당되는 단위를 stack frame이라고 부름.- 중간에 function 호출될 때마다 새로운 stack frame을 하나 생성되고,
이 stack frame안에 그 함수에서 선언된 지역변수(매개변수 포함)들이 할당됨. - 소멸 시에는 맨 나중에 할당된 stack frame부터 소멸됨. 즉, 특정 function이 종료(return문 수행)될 경우 해당하는 stackframe이 소멸됨.
- FILO (First In Last Out, 혹은 LIFO=Last In First Out)을 따름.
- Function call과 stack에 대한 좀 더 자세한 설명은 다음 URL참고 : Function call과 Stack
- 중간에 function 호출될 때마다 새로운 stack frame을 하나 생성되고,
- OS가 해당 프로그램의 process에 할당한 메모리 영역의 상위부분에서 하위부분으로 데이터를 쌓아감.
(stack의 경우 먼저 할당된 argument나 돌아갈 주소가 메모리의 상위영역에 있고, 나중에 할당된 것들은 하위 영역에 있음.)- Heap과 반대임!
- recrusive call 등을 잘못 사용하여 stack area에 문제가 발생시 stack overflow가 발생.
- stack의 크기는 compiler가 계산하여 할당함.
- Heap영역과 영역이 겹치지 않아야 하며 OS가 이를 고려하여 중간영역을 여유롭게 할당함 (컴파일 과정에서 이를 지정하는 등의 옵션도 존재)
Stack은
동적 할당 영역에 속하며, 함수 호출 시마다 runtime 에 메모리를 할당하고 함수가 종료되면 메모리를 해제하는 방식으로 작동함.
이는 프로그램이 실행되는 동안 stack frame이 필요에 따라 추가되고 제거되는 동적인 성격을 가지기 때문임.
다만, stack의 (최대)크기 자체는 보통 컴파일 타임에 고정되며, 운영 체제나 컴파일러에서 정해진 범위 내에서 동작함.
Stack은 OS등에서 워낙 많이 사용되는 자료구조 로서 Queue와 함께 기본적으로 소개됨.
https://dsaint31.tistory.com/entry/CE-Stack
2. 기타
특정 processor들의 경우,
- 메모리의 시작하는 주소 부분 혹은 끝나는 주소 부분에
- interrupt vector나 on-chip I/O device 제어를 위한 레지스터를 위한 영역을 할당하기도 함.
또한 stack 영역보다 상위 영역에 환경변수와 argv, argc 등의 문자열과 포인터가 저장되는 영역이 있으나 일반적으로 그릴 때 생략됨.
3. 정리
메모리 주소 |
영역 이름 | 할당되는 것들 | 생성시점 | 소멸시점 | 할당 메모리 크기 결정 시점 |
쌓는 방법 |
상위주소 | Stack Seg. | Local Variables, Parameters, and so on. |
Function Call | Function End | Compile Time | 상위 주소에서 하위 주소로 |
Heap Seg. | 동적으로 할당된 변수들 |
malloc 등의 함수로 메모리에 할당될 때 |
free 등의 함수로 메모리 해제시. |
Run Time | 하위 주소에서 상위 주소로 |
|
Data Seg. | Global Variables, Static Variables |
프로그램 시작 | 프로그램 종료 | Complie Time | 하위 주소에서 상위 주소로 |
|
하위주소 | Code Seg. | Program Code | 프로그램 시작 | 프로그램 종료 | Compile Time | 하위 주소에서 상위 주소로 |
반응형
'Computer' 카테고리의 다른 글
[DL] Hyperbolic Tangent Function (tanh) (0) | 2023.08.13 |
---|---|
[Util] ZoomIt (0) | 2023.05.20 |
[CE] Magnetic Tape (자기테이프) (0) | 2022.12.10 |
WSL 2에서 VHD(가상 하드 디스크)의 크기 확장 (0) | 2022.08.06 |
[Conda] Install Conda on WSL2 (miniconda) (0) | 2022.07.17 |