프로그램의 동작 원리
- 사용자가 운영체제(OS)를 통해 프로그램 실행을 요청.
- 하드디스크(HDD)에 저장되어있던 프로그램을 작동시키기 위해 메모리의 코드 영역에 올림.
- CPU가 프로그램 코드를 읽어 메모리를 관리하고 명령문들을 실행.
- 프로그램 실행을 위해 동적메모리가 할당되면 Heap을 아래로 넓히며 FreeStore영역을 사용
- 시스템이 작동하기 위해 CPU가 임시적인 정보를 Stack에 저장해 위로 넓히며 FreeStore영역을 사용
※ Heap 메모리와 Stack 메모리를 많이 사용하면 남은 FreeStore영역이 없어져 메모리가 부족한 상태가 됨.
이해를 위해 편의상 위와 아래로 넓힌다고 했지만,
stack은 높은 주소→낮은 주소 순으로 공간을 채우고 heap은 낮은 주소→높은 주소 순으로 채우기 때문에 반대로 보기도 한다. 그러므로 두 영역이 만나 메모리가 부족해진다는 것에 포커스를 맞추자.
메모리 영역별 설명
메모리는 활용과 기능에 따라 주로 4가지로 구분된다.
- Program Code 영역 : 함수, 상수, 실행할 프로그램의 코드가 저장되고 프로그램 종료시까지 남아있다(기계어 형태). 함수와 상수는 컴파일 단계에서 검사 후 저장된다.
- Data(& BSS) 영역 : 전역변수와 static(정적)변수가 저장되고 프로그램 종료시까지 남아있다. 컴파일 단계에서 검사 후 저장된다.
- Data 영역 : 초기화된 static변수, 전역변수가 저장된다.
- BSS 영역 : 초기화되지 않았거나 0으로 초기화된 static변수, 전역변수가 저장된다. - Heap 영역 : 프로그래머에 의해 동적으로 할당(new(C++), malloc(C)) / 해제(delete(C++), free(C)) 되는 공간이다.
- Stack 영역 : 지역변수와 매개변수가 저장되고, 함수를 빠져나가면 자동 소멸된다.
Code, Data 영역은 컴파일할 때 변수가 저장되는 정적 메모리(영역),
Heap, Stack 영역은 프로그램 실행 중에 생성되고 소멸되는 변수를 저장하는 동적 메모리(영역)다.
프로그래머가 생성한 변수들은 코드에 따라 할당받은 메모리의 영역에 저장된다.
개발 시에는 이 메모리 영역을 크게 Static 영역, Heap 영역, Stack 영역으로도 나눌 수 있다.
정적 메모리는 데이터 영역에 저장되고 지속성이 보장된다.
Heap 메모리는 지속성이 보장되나, 프로그래머가 일일이 메모리 해제를 해주는 등의 꼼꼼한 관리가 필요하다.
반대로 Stack 메모리는 함수를 빠져나가면 자동 소멸되므로 일일이 관리에 신경쓰지 않아도 된다.
+) C/C++에서 전역변수나 정적변수를 선언하면 따로 초기화하지 않아도 자동으로 0으로 초기화되는 것을 확인할 수 있다. 이는 Stack 영역에 저장되는 지역변수, 매개변수와 달리 전역변수와 정적변수는 Data 영역에 저장되기 때문이다.
정적할당과 동적할당의 구분 기준
정적(Static) 할당과 동적(Dynamic) 할당을 구분하는 기준은 '프로그램 실행 중에 메모리 공간을 할당하는지' 이다.
정적 할당은 컴파일 단계에서 메모리를 할당하고, 동적 할당은 실행 단계에서 메모리를 할당한다.
정적 할당
컴파일 단계에서 메모리를 할당하므로 프로그램 실행 시에는 이미 메모리의 크기가 결정되어 있어 나중에 조절할 수 없다. 정적 할당된 메모리는 실행 도중에 해제되지 않고 프로그램이 종료될 때 알아서 운영체제가 회수한다. 이로 인해 메모리 누수는 일어나지 않는다.
- 장점 : 메모리 누수를 걱정하지 않아도 된다. 따로 해제해주지 않아도 운영체제가 자동으로 메모리를 회수해간다.
- 단점 : 할당받는 메모리의 크기가 정해져있어 프로그램이 실행될 때 수정할 수 없다. 이로 인해 메모리 공간의 낭비가 생길 수 있다.
동적 할당
실행 단계에서 메모리를 할당하고, 사용 후 운영체제에 반납하므로 재할당받을 수 있다. 즉 프로세스의 실행 중에 필요한 메모리를 운영체제에 요구해 할당받고 해제하는 것이 가능하다.
포인터를 사용해 Heap 영역을 가리켜 해당 공간을 할당하는 것이 특징이다.
할당된 메모리는 프로세스가 동작중일 때 명시적으로 해제하거나 garbage collection(GC)이 수행되기 전까지는 그대로 유지된다(프로세스가 종료되어도 운영체제에 반납). C/C++에는 GC가 없어 별도로 해제해줘야 한다.
- 장점 : 원하는 만큼의 메모리가 맞춤으로 할당되어 메모리 공간의 낭비가 발생하지 않는다. 즉, 경제적이다.
- 단점 : 사용하지 않는 메모리를 직접 해제해주지 않으면 메모리 누수가 생길 수 있다.
※ 주의할 점 : 메모리의 동적/정적 영역 구분과 변수들의 동적/정적 할당 구분은 별개다.
예를 들어 지역변수와 매개변수는 컴파일 단계에서 메모리 공간을 할당받으므로 정적 할당인데, 정작 할당받는 공간은 동적 영역인 Stack영역이다. 컴파일 단계에서 공간을 할당받으니 실행 단계에서는 공간의 크기를 조절할 수 없지만, Stack영역은 동적 영역이기 때문에 실행 중 얼마든지 해제할 수 있다.
정적 할당 | 동적 할당 | |
메모리 영역 | Stack | Heap |
메모리 할당 | 컴파일 단계 | 실행 단계 |
메모리 크기 | 고정. 실행 중 조절 불가 | 실행 중 유동적으로 조절 |
포인터 사용 여부 | 미사용 | 사용 |
할당 해제 | 함수가 사라질 때 자동 반납 | 사용자가 원할 때 직접 반납 |
메모리구조 참조 블로그 : https://myblog.opendocs.co.kr/archives/1301
정적/동적할당 참조 블로그 : https://m.blog.naver.com/PostView.naver?blogId=eludien&logNo=221462352935&proxyReferer=https:%2F%2Fwww.google.com%2F
'[C_C++]이론 공부 > 이론+STL' 카테고리의 다른 글
[C++ STL] set 사용법 위주 공부 (0) | 2021.06.29 |
---|---|
[C++ STL] vector(벡터) 공부 (0) | 2021.06.14 |
[C++] 클래스(class) 기본 (0) | 2021.06.01 |
OOP(객체지향 프로그래밍)의 주요특징 (0) | 2021.05.21 |
[C++] 데이터 타입(자료형) (0) | 2021.05.20 |