일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 컴퓨터네트워크
- linux
- Go
- 자료구조
- dockerfile
- 데이터 파이프라인
- airflow
- S3
- 정리
- 운영체제
- 데이터 웨어하우스
- sql
- Django
- Docker
- 데브코스
- PYTHON
- redshift
- airflow.cfg
- AWS
- 데이터엔지니어링
- TIL
- HADOOP
- TCP
- 컴퓨터 네트워크
- 종류
- 가상환경
- 데이터베이스
- http
- 파이썬
- 데이터 엔지니어링
- Today
- Total
홍카나의 공부방
[운영체제] 힙 메모리 영역과 스택 메모리 영역 본문
프로세스의 메모리 사용
일반적으로 우리가 사용하는 컴퓨터에서는 프로세스를 메모리에다가 배치할 때 운영체제가 데이터 구조를 아래와 같은 그림으로 배치한다.
...다시 보니까 너무 대충 그렸나 싶기도 하고, 좀 더 자세한 그림을 가져오겠다.
이렇게 된다! 참고로 커널 영역의 경우 운영체제의 영역이니 프로세스의 메모리 구조를 주제로 잡는 이 글에서는 다루지 않겠다. 어떠한 프로그램이 데이터를 저장할 때 여러 영역들에다가 데이터를 나눠서 저장하게 되는데, 영역을 괜히 나눈게 아닐 것이다. 어떤 기준으로 나눴는지 살펴보자.
1. 데이터(data) 영역
- 전역 변수, static 변수로 선언한 데이터들이 해당 영역에 들어간다.
- 컴파일 시점에 크기가 결정되며, 프로그램 시작과 동시에 할당되고 종료시 소멸된다.
2. 힙(Heap) 영역
- 동적으로 할당된 데이터들이 들어가는 영역이다. ( C에서의 malloc(), C++에서의 new )
- 런타임 시점에서 사이즈가 결정되며, 할당 해제 시점은 C++의 경우 프로그래머가 직접 delete하는 시점이다.
3. 스택(Stack) 영역
- 지역 변수와 함수의 매개 변수를 저장한다.
- 컴파일 시점에 크기가 결정되며, 함수가 호출될 시 할당되고 함수가 종료(return)될 때 소멸한다.
코드 예시로 살펴보자. 아래 C++ 프로그램 코드에서 변수 a가 담고 있는 정수 1은 어느 메모리 영역에 데이터가 할당되었을까?
#include <iostream>
int main()
{
int a = 1;
return 0;
}
스택 메모리 영역이다. 변수 a는 main() 함수의 지역 변수이고, 컴파일 시점에 4바이트(int 자료형의 크기다.)만큼 스택 메모리에 영역을 차지하게 될 것이다.
#include <iostream>
static float d = 3.3;
int* mem_test(int a)
{
int c = 1;
return new int(a);
}
int main()
{
int *main1 = new int(1234);
int *main2 = mem_test(5678);
delete main1;
delete main2;
return 0;
}
위 코드에서 정수형 포인터 main1, main2와 mem_test 함수 내부에 있는 정수형 변수 c, 그리고 static 정수형 전역 변수 d는 어느 메모리 영역에 할당되었을까?
- main1: 힙 메모리에 할당된 변수
- main2: 힙 메모리에 할당된 변수 (mem_test 함수에서 할당)
- c: 스택 메모리에 할당된 지역 변수
- d: 데이터 영역에 할당된 static 전역 변수
마지막으로 예시로 들진 않았지만 메모리상의 가장 낮은 주소에 위치한 코드(텍스트)영역에는 프로그램 코드들이 실행 가능한 기계어 형태로 들어가게 된다.
힙 메모리의 데이터 할당
힙 메모리 영역에 데이터를 할당하는 것은 Dynamic Memory Allocater가 담당한다. 동적 메모리 관리자라고 번역하던데, 대표적으로 C의 Malloc()이 동적 메모리 관리자 역할을 하는 함수라고 볼 수 있다.
Dynamic Memory Allocater는 아래와 같이 두 가지 유형으로 분류할 수 있다.
- Explicit Memory Allocator : 응용 프로그램이 allocate와 free 연산을 직접 수행한다. 즉, 프로그래머가 직접 메모리에 데이터를 할당/해제하게 되며, C++에서는 new와 delete 명령어를 이용해서 수행할 수 있다. 프로그래머가 직접 할당/해제한다는 것을 돌려 말하면, 대신 해제해주는 누군가가 없다는 이야기다. 운영체제도 관섭을 안한다! 그래서 항상 new를 쓸 때 delete를 함께 쓰지 않는 실수를 범하지 않도록 주의해야 한다. memory leak이 발생하고 싶지 않다면 말이다......
- Implicit Memory Allocator : 응용 프로그램이 allocate만 하고, free 연산은 하지 않는다. 즉, 프로그래머가 직접 힙 메모리 영역 할당을 요청하긴 하는데, 해제 과정은 내부적으로 자동 수행되는 방식이다. 사용하지 않는 Heap 영역을 대신 누군가가 해제해준다는 이야기다. Java의 가비지 콜렉션이 대표적인 예시고, 자바스크립트에서도 가비지 컬렉션이 쉴 새 없이 동작한다.
'Operating System' 카테고리의 다른 글
[운영체제] Ch.6 프로세스 동기화와 상호배제, 세마포어 Python 구현 (0) | 2023.03.28 |
---|---|
[운영체제] Ch.5-2 스케쥴링 알고리즘 (0) | 2023.03.24 |
[운영체제] Ch.5-1 프로세스 스케쥴링의 목적, 기준, 단계, 정책 (0) | 2023.03.22 |
[운영체제] Ch.4 쓰레드의 개념, 유저 쓰레드, 커널 쓰레드 (0) | 2023.03.21 |
[운영체제] Ch.3 프로세스의 정의, 상태, state diagram, 인터럽트 (0) | 2023.03.18 |