프로세스의 가상 주소 공간은 대표적으로 코드, 데이터, 힙, 스택 영역으로 나눌 수 있습니다. 각 영역은 저장하는 정보와 생명주기가 다릅니다.
- 코드(Code/Text): 실행할 기계어 명령을 저장하며, 보통 읽기·실행 권한을 가집니다.
- 데이터(Data/BSS): 전역 변수와 정적 변수를 저장합니다. 일반적으로 0이 아닌 초기값이 있는 변수는 Data, 0으로 초기화되거나 명시적으로 초기화하지 않은 변수는 BSS에 배치됩니다.
- 힙(Heap): 실행 중 동적으로 할당한 데이터를 저장하며, 할당자나 런타임이 수명을 관리합니다.
- 스택(Stack): 함수 호출에 필요한 지역 변수, 매개변수, 복귀 주소 등을 관리하며, 스레드마다 별도로 가집니다.
실제 배치는 운영체제·실행 파일 형식·컴파일러에 따라 달라지고, 공유 라이브러리나 메모리 매핑 영역도 존재합니다. 핵심은 힙은 프로세스 내에서 공유되고, 스택은 각 스레드의 호출 흐름을 관리한다는 점입니다.
힙에 할당한 객체를 지역 변수로 참조하면 객체도 스택에 저장되나요?
참조와 참조 대상은 구분해야 합니다. 지역 변수에 담긴 주소나 참조는 스택 또는 레지스터에 있을 수 있지만, 그 참조가 가리키는 동적 할당 데이터는 힙에 존재할 수 있습니다.
스택 오버플로와 메모리 누수는 어떻게 다른가요?
스택 오버플로는 깊은 재귀 등으로 스택 공간의 한도를 넘는 현상입니다. 메모리 누수는 더 이상 필요하지 않은 할당을 해제하지 못하는 현상이며, GC 환경에서도 불필요한 객체의 참조를 유지하면 발생할 수 있습니다.
메모리를 할당하면 물리 메모리도 즉시 확보되나요?
항상 그렇지는 않습니다. 요구 페이징을 사용하는 운영체제는 가상 주소 공간을 먼저 마련하고 실제 접근 시 Page Fault를 통해 물리 페이지를 연결할 수 있습니다.
스택 할당이 힙 할당보다 빠른 이유는 무엇인가요?
스택은 일반적으로 스택 포인터를 이동하는 것만으로 공간을 확보하고, 함수가 끝나면 포인터를 되돌려 한꺼번에 해제할 수 있습니다. 힙은 크기와 수명이 제각각이어서 할당자가 적절한 빈 블록을 찾고 메타데이터와 단편화를 관리하며, 상황에 따라 동기화나 운영체제에 대한 추가 메모리 요청도 수행합니다. 다만 TLAB이나 최적화된 할당자처럼 구현에 따라 차이가 줄어들 수 있습니다.
초기화되지 않은 정적 변수와 전역 변수는 같은 영역에 저장되나요?
C와 ELF 실행 파일을 기준으로, 초기화하지 않았거나 0으로 초기화한 전역 변수와 정적 저장 기간을 가진 변수는 일반적으로 BSS 영역에 배치되고 실행 시작 시 0으로 초기화됩니다. 전역 변수와
static변수는 가시성과 연결 방식이 다를 수 있지만, 둘 다 정적 저장 기간을 가지면 초기화 여부에 따라 BSS 또는 Data 영역에 배치될 수 있습니다. 일반 지역 변수는 이에 해당하지 않습니다.