-
스택이 매우 커질 수 있다면 힙은 불필요할까?개발/기타 2025. 4. 6. 22:24
https://www.youtube.com/watch?v=9TSojdIr8Q0
이 영상을 보고 "나라면 어떻게 답변했을까?" + 부족했던 점을 작성하고자 한다.
알고 있는 지식, ChatGPT와 더불어 이것 저것 찾아보겠지만 잘못된 내용이 있을 수 있습니다.
잘못된 내용이 있다면 댓글로 알려주시면 감사하겠습니다 :)
나라면 어떻게 답변했을까? (잘못된 내용이 있습니다.)
메모리 할당 영역은 Data, Stack, Heap 영역 이렇게 3가지가 있는 것으로 알고 있다.
Data영역
- 전역변수, static 변수 등이 존재
Stack 영역
- 고정 크기, 지역변수, 매개변수, 함수 리턴 주소가 존재
Heap 영역
- 동적 크기, 동적 할당 변수 존재
이정도로 배경지식이 있는 상태이다.
그렇다면, 스택이 매우 커질 수 있다면 힙은 불필요할까?
불필요하냐고 물어본다면
비효율적인 데이터 구조도 괜찮다면 Heap의 역할을 여러 개의 Stack을 사용할 수 있다면 대체할 수 있다고 말했을 것 같다.하지만 Heap과 Stack 구조의 특성이 있고 Stack의 경우 LIFO구조이므로 우선순위에 따라 데이터 구조가 달라지는 Heap이 유리한 곳이 있지 않을까? 라고 막연하게 생각된다.
그리고 Heap은 Stack을대체할 수 없다고 한다.
왜 대체할 수 없을까?
스택과 힙은 각각 다른 목적과 특성을 갖고 있어, 스택의 크기를 늘리거나 여러 개의 스택을 생성한다고 하더라도 힙이 제공하는 동적 할당, 임의 접근, 생명주기 독립성 등의 기능을 대체할 수 없다.
Stack은 함수 호출과 관련된 일시적, 정형화된 데이터를 빠르게 처리하는 데 최적화되어 있고,
Heap은 동적이고 복잡한 데이터 구조 및 객체의 수명 관리에 필수적이다.
1. 할당 방식과 생명주기 관리의 차이
- Stack
- 함수 호출에 의존한 자동 관리로, 함수가 종료되면 메모리가 자동 해제되는 선형 메모리 공간
- 지역 변수나 임시 데이터를 위한 짧은 수명의 저장소로 최적화되어 있음
- 지역변수의 수명 추적 가능
- Heap
- 동적으로 메모리를 할당하고 해제할 수 있어, 함수 호출과 관계없이 데이터의 생명주기를 프로그래머가 제어할 수 있음
- 장기간 유지되어야 하는 데이터나 동적 크기 데이터를 저장하기에 적합
2. 메모리 접근 패턴과 구조적 제약
- Stack
- LIFO 방식이므로 임의 순서의 데이터 접근이나 중간에 할당된 메모리 블록의 해제가 불가능
- 만약 여러 스택을 사용한다고 해도 각 스택은 여전히 LIFO 구조에 머무르므로, 자유로운 임의 접근이나 비순차적 해제가 어려움
- Heap
- 임의의 순서로 할당과 해제가 가능하며, 데이터 구조의 복잡도에 따라 다양한 메모리 접근 패턴을 지원
3. 목적과 사용 사례의 근본적 차이
- Stack
- 함수 호출, 임시 데이터, 빠른 성능이 요구되는 상황에 최적화되어 있으며, 고정적이고 예측 가능한 메모리 사용을 보장
- Heap
- 객체 지향 프로그래밍에서 객체나 동적 배열 등 런타임에 크기나 수명이 결정되는 데이터를 위해 설계되었으며, 복잡한 데이터 구조를 효율적으로 관리
4. 스택의 멀티스레딩 이슈
- 스택에 특정 함수 범위를 넘어 존재해야 하는 변수(또는 인스턴스) 관리가 어려움
- 특히, 멀티스레딩 환경에서 여러 스레드가 동시에 접근할 필요성이 있는 대상 메모리가 필요할 경우 구현이 어렵거나 구조적으로 불가능
+ Heap 메모리 파편화
영상 내용 중에 Heap 메모리 파편화에 대한 내용도 있기에 작성해보겠다.
파편화의 종류
- 외부 파편화 (External Fragmentation)
- 할당과 해제가 반복되면서 사용 가능한 자유 메모리 블록들이 산발적으로 존재하게 되어, 총 여유 메모리가 충분함에도 불구하고 연속된 큰 메모리 블록을 확보하지 못하는 현상
- 내부 파편화 (Internal Fragmentation)
- 메모리 할당 단위가 고정되어 있을 때, 요청한 크기보다 큰 블록을 할당받아 남는 미사용 영역이 발생하는 현상
파편화 발생 이유?
1. 동적 메모리 할당 및 해제
- 불규칙한 메모리 사용
- 메모리를 할당하고 해제하는것을 반복되다보면 사용 중인 블록/해제된 블록이 무작위로 분포
- 이로 인해 연속된 큰 메모리 블록 확보가 어려워지는 외부 파편화 발생
2. 고정 크기의 할당 단위와 내부 파편화
- 페이지 단위 관리 : 대부분의 OS는 물리 메모리를 일정 크기의 페이지 단위(ex. 4KB)로 관리
- 요청 크기와 할당 단위 불일치
- 실제 요청하는 메모리 크기가 페이지 크기보다 작아도, 최소로 할당되는 페이지 크기는 고정
- 페이지 내 남는 공간이 낭비 -> 내부 파편화가 발생
3. 할당 알고리즘의 한계
- 알고리즘 특성: OS는 메모리 할당을 위해 베스트 핏, 퍼스트 핏, 버디 시스템 등 다양한 알고리즘을 사용
- 최적화의 어려움
- 특정 상황에서 메모리 사용을 최적화하는 알고리즘
- 동적이고 다양한 요청 패턴에 항상 최적의 연속 공간을 제공하지 못해 파편화 문제를 완전히 해소할 수 없음
4. 가상 메모리와 물리 메모리의 매핑 문제
- 가상-물리 주소 매핑
- OS는 가상 메모리 시스템을 통해 논리적 연속성을 제공하지만, 실제 물리 메모리는 여러 개의 분리된 블록으로 구성
- 연속성 보장 어려움
- 이 매핑 과정에서 물리 메모리의 연속적인 영역이 부족해지는 문제가 발생할 수 있으며, 이는 결국 파편화로 이어짐
5. 하드웨어 제약
- 메모리 모듈 특성
- 하드웨어 수준에서는 메모리 칩이 물리적으로 일정한 크기와 형태로 제조되므로, 이를 완벽하게 연속된 공간으로 활용하기 어려움
- 물리적 제한
- 메모리 컨트롤러나 칩셋 설계 상의 제약으로 인해, 실제 물리 메모리에서 연속적인 큰 블록을 유지하는 것이 힘들어짐
해결 및 완화 방법
- 메모리 풀 (Memory Pool) 사용
미리 일정 크기의 메모리를 할당해 놓고, 해당 풀 내에서 동일한 크기의 메모리 블록을 재사용하여 파편화를 줄이는 방법 - 가비지 컬렉션과 메모리 재배치
가비지 컬렉션을 사용하는 런타임에서는 사용되지 않는 메모리를 회수하고, 필요 시 메모리 재배치를 통해 연속된 메모리 영역을 확보
반응형'개발 > 기타' 카테고리의 다른 글
쿠버네티스란? (0) 2025.02.23 25년 계획 및 23~24년 회고 (0) 2024.12.29 SSAFY 1학기 회고 (0) 2023.12.11 - Stack