✅ 해당 글은 저의 주관이 가득 섞인 내용입니다. 특히 질문한 이유, 면접관의 의도 등은 개인적인 생각임을 밝힙니다.
(0) 시간이 없어서 죄송해요 전체 글을 못읽겠어요. 빠르게 원하는 것만 가져갈게요!
프로세스 메모리 구조는 4가지로 나눌 수 있습니다.
(1) Stack 영역 : 함수 호출 시 지역, 매개변수가 저장되는 공간입니다. 함수가 종료되면 호출한 순서 반대로 해제합니다.
- 데이터가 일시적으로 저장되는 영역입니다. 구현한 함수가 호출되어, 호출된 함수의 반환 주소, 반환 값, 매개변수가 저장된 스택 프레임이 생성됩니다. 그 후, 생성된 스택 프레임이 실행이 완료되어 함수를 반환했다면 스택 프레임이 해제됩니다. 이와같은 과정은 Last In First Out 방식으로 수행됩니다.
(2) Heap 영역 : 사용자가 동적으로 할당, 해제할 변수들이 저장됩니다.
동적으로 메모리를 할당할 수 있는 영역입니다. 동적으로 메모리를 할당하기 위해 프로그램 실행 중 시스템 호출을 사용해 메모리를 할당할 수 있고, 해제도 가능합니다. 대표적인 예시로 C언어의 malloc, realloc, calloc가 존재합니다.
(3) Data 영역 : 전역, 정적 변수를 저장하거나 할당하고 실행하기 전에 초기화하는 영역입니다.
(4) Code 영역 : 컴파일된 기계어가 저장됩니다.
(1) 질문한 이유가 뭐예요?
위 질문을 한 이유는 프로세스가 어떻게 구성되어 있는지 알고 있냐로 판단하면 될 것 같습니다. 우리는 이전에 디스크에 있던 프로그램이 메모리에 적재(Load)되면서 운영체제의 제어를 받고 있는 상태를 프로세스라고 말했습니다. 그렇다면 메모리에 적재되었을때 해당 프로세스는 어떤 메모리 구조를 띄고 있을까? 아주 간단하지만 알고 있는지 물어봤다고 볼 수 있습니다.
천천히 4가지 영역에 대해서 설명해보도록 하겠습니다.
📌Stack 영역은 C++로 프로그램을 작성할 때, 우리는 main 함수를 먼저 작성을 합니다. 프로그램의 흐름의 중심이 된다고 볼 수 있습니다. 먼저 main 함수가 Stack 영역에 생성되면서 main 함수 내에 존재하는 함수가 차례로 Stack 영역에 생성되면서 차례차례 쌓이게 됩니다. 그 과정은 Last In First Out으로 동작하게 되며 처음 생성된 main 함수의 스택 프레임이 반환되면서 프로그램이 끝난다고 생각하면 됩니다. 그리고 이 과정을 간단 명료하게 정리하면 아래와 같습니다.
Stack 영역은 데이터가 일시적으로 저장되는 영역입니다. 구현한 함수가 호출되어, 호출된 함수의 반환 주소, 반환 값, 매개변수가 저장된 스택 프레임이 생성됩니다. 그 후, 생성된 스택 프레임이 실행이 완료되어 함수를 반환했다면 스택 프레임이 해제됩니다. 이와같은 과정은 Last In First Out 방식으로 수행됩니다.
📌Heap 영역은 C/C++ 프로그래밍 언어로 메모리를 할당받을 때 사용하는 malloc, calloc, realloc와 같은 시스템 콜( 커널 영역에 접근해서 호출하는 함수)을 사용해서 메모리를 할당받습니다. 할당 받은 메모리 영역은 Heap 영역에 할당됩니다. 하지만 해제는 개발자의 몫입니다. 실제로 해제해주지 않는다면 메모리 누수(Memory Leak)이 발생되어 프로그램에 악영향을 미치게 되어 종료 되는 대참가사 발생하게 됩니다. 또한, 이를 해결하기 위해서 C/C++에서는 스마트 포인터를 사용해 해당 실수를 예방하는데요. 이에 대해서 더 자세히 다음 글로 작성을 해보겠습니다. Heap 영역도 아래와 같이 간단 명료하게 말할 수 있습니다.
Heap 영역은 동적으로 메모리를 할당할 수 있는 영역입니다. 동적으로 메모리를 할당하기 위해 프로그램 실행 중 시스템 호출을 사용해 메모리를 할당할 수 있고, 해제도 가능합니다. 대표적인 예시로 C언어의 malloc, realloc, calloc가 존재합니다. 그리고 해제하지 않는다면 메모리 누수를 발생시킬 수 있습니다.
📌Data 영역은 전역변수나 정적변수를 저장하거나 할당하고 실행하기 전에 초기화 합니다. 해당 영역은 초기화를 기준으로 두가지 영역으로 나눌 수 있습니다. 왜 초기화를 기준으로 해당 영역을 나눌 수 있을까요?
메모리의 크기를 차지하고 있냐, 아니냐의 문제입니다. 그래서 Data 영역과 BSS 영역으로 구분할 수 있습니다. Data 영역은 초기화된 변수들을 저장합니다. 컴파일 타임에 메모리를 확보해 값을 저장합니다. 하지만, BSS 영역에 저장된 변수는 초기화 되지 않은 변수들 입니다. 런타임에 메모리를 확보하기 때문에 미리 메모리를 점유하고 있지 않아 메모리를 낭비하지 않을 수 있습니다. 초기화를 기준으로 Data 영역을 구분할 수 있는데요. 간단하게 정리하자면 아래와 같습니다.
초기화를 하는 과정은 컴파일 타임에 메모리를 확보해 값을 저장하게 됩니다. 그로인해 메모리를 차지하고 있게 되는 것입니다. 하지만, 초기화되지 않은 변수는 런타임에 메모리를 확보해 미리 메모리를 점유하고 있지 않습니다. 이를 통해 메모리를 낭비하지 않을 수 있고, 이들은 데이터 영역의 끝에서 시작하게 됩니다.
Code 영역은 컴파일된 기계어가 저장되어있는 영역으로 생가하시면 됩니다. 딱히 설명할 내용이 있지 않습니다. 아마도 제가 자세히 몰라서 그럴 수도 있습니다. 이 영역의 특징으로는 읽기 전용이므로 프로그램이 코드 영역을 침범해 쓰기를 시도하면 오류가 발생한다는 점입니다.
(2) 해당 질문을 한 면접관의 의도는 무엇일까요?
프로세스가 어떠한 메모리 구조를 갖고 있고, 해당 영역의 역할이 어떤 것인지 궁금했다고 생각하면 될 것 같습니다. 프로세스가 어떤 방식으로 동작하는지 설명할 수 있고, 우리가 작성한 코드가 어떤 영역에 위치하고 있는지 알고 있는가에 대한 질문이였다고 생각합니다. 해당 질문으로 다양하게 뻗어나갈 수 있지만, 현재 제가 생각하기엔 여러가지 중요한 내용들이 많기 때문에 면접관들도 이 질문에 힘을 쏟진 않을 것이라 생각합니다.
하지만, 글을 작성하다보면 해당 부분에서 중요한 부분이 다시 발생할 수 있기 때문에..예를 들어 Data 영역이 가상 주소 공간이라는 점과 같은 현재는 이해하지 못한 부분이 추후에 중요해질 수 있습니다. 그렇기에 해당글에서는 말을 아끼도록 하겠습니다.
여기까지 아주 기본적인 프로그램, 프로세스 그리고 프로세스의 메모리 구조에 대해서 작성했습니다. 꾸준히 제 생각을 글로 풀어내는 것이 상당히 어렵네요. 글을 계속해서 써내려가면서 저도 이해하고 이 글을 읽는 다른 누군가도 이해할 수 있게 글을 작성해야겠습니다. 그래야 나중에 시니어 레벨이 되었을때 주니어 또는 신입과의 대화에서도 잘 이어나갈 수 있을것이기 때문입니다. 여기까지 적겠습니다.
다음 씨면기작은 🔜다른 독립적인 컨텐츠 입니다.
'CS > 운영체제' 카테고리의 다른 글
[씨면기작] 프로세스의 문맥교환(Context Switching)에 대해서 설명해주세요. (0) | 2024.04.08 |
---|---|
[씨면기작] 프로세스의 상태변화에 대해서 설명해주세요. (2) | 2024.04.07 |
[씨면기작] 운영체제란 무엇인지 아는대로 설명해주세요 (0) | 2024.04.03 |
[씨면기작] 프로세스와 프로그램의 차이는 무엇인가요? (0) | 2024.04.03 |
(1) 운영체제에 관해서_ (0) | 2022.05.04 |