프로세스의 메모리 영역 구조를 간단히 표현하면 다음과 같다.
각 메모리 구조는 다음과 같이 나뉜다.
스택(Stack): 지역 변수, 함수의 매겨변수(parameter), 반환되는 주소 값 등이 저장되는 영역이다. 높은 주소 값에서 낮은 주소 값으로 메모리가 할당되며, 영역의 크기는 컴파일 때 결정된다.
힙(heap) : 사용자에 의해 동적 메모리 할당이 일어나는 영역이다. C 언어에서 malloc() 으로 할당되는 영역이라고 보면 된다. 낮은 주소 값에서 높은 주소 값으로 메모리가 할당되며, 영역 크기는 런타임 때 결정된다.
- 컴파일은 프로그래밍 언어로 작성된 소스 코드를 기계어 또는 중간 코드(바이트코드)로 변환하는 과정이다.
- 런타임은 컴파일이 완료된 프로그램이 실행되는 시점을 말합니다. 즉, 컴파일된 코드가 실제로 수행되는 동안의 모든 상황을 의미한다.
데이터(data) : 전역 변수, 정적 변수, 배열, 구조체 등이 저장되는 영역이다. 데이터 영역은 세부적으로 BSS(Block Stated Symbol) 영역과 데이터 영역으로 다시 나눌 수 있다. BSS 영역은 초기화하지 않은 변수를, 데이터 영역은 초기화한 변수를 저장한다.
코드(code) : 실행할 코드가 기계어로 컴파일되어 저장되는 영역으로, 텍스트 영역이라고도 한다.
여기서 스택 영역과 힙 영역은 동적으로 메모리 할당이 가능해 두 영역 사이에 빈 메모리 공간이 존재한다.
스택 영역은 LIFO(Last In First Out, 후입선출) 방식으로, 노은 주소 값에서 낮은 주소 값 순서로 사용한다.
힙 영역은 FIFO(First In First Out, 선입선출) 방식으로 낮은 주소 값에서 높은 주소 값 순서로 사용한다.
힙은 메모리 위쪽 주소부터 할당되고, 스택은 메모리 아래쪽 주소부터 할당되기 때문에 각 영역이 상대 공간을 침범하는 일이 발생할 수 있다.
스택 영역이 힙 영역을 침범하는 경우를 스택 오버플로우, 힙 영역이 스택 영역을 침범하는 경우를 힙 오버플로우라고 한다. 여기서 오버플로우란(메모리 공간에서 할당할 수 있는 최대 범위를 넘어가는 것을) 의미한다.
면접 질문 예상
1. "스택과 힙 영역을 설명해주세요."
답변: 스택(Stack)과 힙(Heap)은 프로그램이 실행될 때 사용하는 두 가지 주요 메모리 영역입니다.
- 스택은 함수 호출 시 자동으로 할당되는 고정된 크기의 메모리 영역입니다. 스택은 LIFO(Last In, First Out) 구조로 데이터를 관리하며, 함수의 지역 변수와 호출 스택 프레임을 저장합니다. 스택 메모리는 매우 빠르게 접근할 수 있지만, 크기가 고정되어 있고 제한적입니다. 함수가 종료되면 자동으로 할당된 메모리가 해제되므로 메모리 관리를 프로그래머가 직접 할 필요는 없습니다.
- 힙은 동적으로 메모리를 할당할 수 있는 영역으로, 프로그램 실행 중 필요한 만큼 할당하고 해제할 수 있습니다. 힙 메모리는 동적 배열, 객체, 복잡한 데이터 구조 등을 저장하는 데 사용됩니다. 힙의 메모리 관리는 프로그래머가 명시적으로 수행해야 하며, 잘못된 메모리 관리는 메모리 누수와 같은 문제를 일으킬 수 있습니다. 또한, 힙은 스택보다 메모리 접근 속도가 느리고, 할당 및 해제가 상대적으로 복잡합니다.
2. "힙 영역에서 메모리 누수는 어떻게 예방할 수 있습니까?"
답변: 힙 영역에서 메모리 누수는 동적으로 할당한 메모리를 적절히 해제하지 않았을 때 발생합니다. 메모리 누수를 예방하기 위해 다음과 같은 방법을 사용할 수 있습니다:
- 명시적 메모리 해제: C와 C++ 같은 언어에서는 동적으로 할당한 메모리를 사용한 후에는 반드시 free() 또는 delete를 사용하여 메모리를 해제해야 합니다.
3. "스택 오버플로는 무엇이며, 왜 위험한가요?"
답변: **스택 오버플로(Stack Overflow)**는 프로그램의 호출 스택 크기를 초과하는 경우에 발생하는 오류입니다. 일반적으로 재귀 함수 호출이 종료되지 않거나, 함수가 너무 많은 메모리를 할당할 때 발생할 수 있습니다.
- 원인: 스택 오버플로는 주로 다음과 같은 상황에서 발생합니다:
- 무한 재귀 호출: 함수가 자신의 호출을 무한히 반복하여 스택을 계속 채우는 경우.
- 큰 데이터 할당: 스택에 큰 지역 변수를 할당하는 경우.
- 위험성: 스택 오버플로가 발생하면 프로그램이 강제로 종료될 수 있습니다. 더 나아가 스택 오버플로는 메모리의 다른 중요한 부분을 덮어쓸 수 있어서 프로그램의 비정상적인 동작이나 보안 취약점을 초래할 수 있습니다. 예를 들어, 악의적인 사용자가 스택 오버플로를 유도하여 실행 가능한 코드를 삽입하고 실행시킬 수 있습니다(버퍼 오버플로 공격).
- 예방 방법: 스택 오버플로를 예방하려면 재귀 호출의 깊이를 제한하고, 필요한 경우 재귀 대신 반복문을 사용하여 큰 지역 변수 할당을 피해야 합니다. 또한, 프로그램의 호출 스택 크기를 고려하여 충분한 스택 공간을 확보해야 합니다.
'cs > 운영체제' 카테고리의 다른 글
[운영체제] 운영체제의 메모리를 관리 전략 (0) | 2024.09.10 |
---|---|
값 형식 / 참조 형식 이란 ? (0) | 2024.08.27 |