Coding Memo

스택과 힙 (stack & heap), 메모리 레이아웃 본문

etc

스택과 힙 (stack & heap), 메모리 레이아웃

minttea25 2023. 6. 25. 14:55

스택과 힙?

 

프로그램 실행 중 함수 호출 스택, 변수 데이터 등을 저장하는 메모리 영역(segment)를 말한다.

 

프로세스의 메모리 레이아웃


kernel

 

Os가 상주하는 보호된 메모리 영역으로 시스템 리소스를 관리한다.
커널코드, 데이터 구조, 장치 드라이버등의 필수 구성요소를 포함하고 있다.

사용자 프로세스는 일반적으로는 커널 공간에 직접 액세스 할 수 없다.


text (code)

 

프로그램의 실행 코드를 저장하고 있는 부분으로 읽기 전용 메모리 영역이다.

프로세서가 실행하는 명령이 포함되어 있으며, 일반적으로는 한 프로그램의 여러 인스턴스간 공유되어 사용해 자원 절약을 한다.

text segment

실행 코드가 있는 부분을 text 메모리 영역에 저장한다.


data

 

프로그램 실행 시작 전에 초기화되는 static 및 global 변수 (정적 변수 및 전역 변수)가 저장되는 영역이다.

data

g_n 이라는 이름의 int 타입 변수가 10으로 초기화 되면서 전역 변수로 선언되어 있다. 이 값은 data 영역에 저장된다.


bss

 

Block Started by Symbol, 초기화 되지 않는 변수를 저장하고 있는 메모리 영역으로 보통 0이나 null의 값을 가지고 있을 수 있다.

bbs

위 코드에서 g_n2가 선언되었지만 초기화 되지 않았으므로 bss 영역에 저장된다.

 

Note: (C) 초기화 되지 않는 전역변수의 경우 일반적으로 컴파일러와 링커가 그 변수의 길이만 오브젝트 파일에 저장하고, 이후 로더가 프로그램 로드시, bss 섹션을 위한 메모리를 할당하고 초기화 한다.


stack

 

지역 변수 (local variables), 함수 호출 정보 (function call information)을 가지고 있는 메모리 영역이다.

쓰레드마다 스택을 가지고 있고 LIFO (Last In First Out)의 구조를 가지고 있다.
(자료 구조에서의 스택과 동일하다.)

stack

함수에서의 지역변수와 함수 호출 정보가 있는 영역이 스택 영역이다.

 

Note: 함수 호출 정보에는 frame pointer, return address 등이 있다.


heap

 

Runtime에 메모리를 할당하는데 사용되는 동적(dynamic) 메모리 영역이다.

어떤 순서로든 액세스가 가능하다.

메모리를 할당하고 해제할 시에 명시적인 할당/해제가 필요하다.

(C/C++: new, malloc, free, delete)

heap

new 키워드를 통해 명시적으로 공간을 할당해주고 delete로 할당된 공간을 해제한다. 할당된 데이터는 heap 영역에 저장된다.

(보통 위와 같이 일반 타입을 동적할당 해주거나 객체지향프로그래밍 언어(C#, Java 등)에서 객체를 할당할 때 heap 영역에 저장하게 된다.)


힙 in Java and C#

 

Java와 C#에는 보통 프로그래머가 직접 명시적으로 동적할당을 하거나 메모리를 해제하지 않는다.

Java와 C#에서는 객체에 대한 인스턴스의 메모리 할당 및 할당 해제를 각각 언어의 런타임 환경에서 관리한다.

런타임 중 더 이상 참조되지 않는 메모리를 자동으로 식별하고 해제한다.

자동 메모리 관리를 제공하기 때문에 메모리 누수 및 기타 메모리 관련 오류를 줄일 수 있다는 이점이 있지만, 상황에 따라 객체 참조를 적절하게 관리하여 메모리 사용을 최적화하고 힙을 불필요하게 사용하는 것을 피하는 것이 중요하다.

 

Java - Java Virtual Machine (JVM), (Garbage Collector)

C# - Common Language Runtim (CLR)


힙과 스택 비교

  Heap Stack
Allocation 명시적으로 할당 및 해제 프로그램의 런타임 시스템 또는 컴파일러에 의해 자동으로 관리
Size 스택보다 큼
(사용 가능한 시스템 메모리에 따라 커질 수 있음)
일반적으로 제한된 공간
(시스템이나 컴파일러에 의해 결정)
Speed 스택에 비해 느림
(간접 참조 및 포인터 조작필요, 어디서든지 액세스 가능)
빠름
(간단한 메모리 포인터 조작)
Usage 오래 지속되어야 하는 데이터 구조, 개체, 배열 등의 비교적 큰 데이터 저장 함수 호출, 지역 변수 및 기타 단기 데이터 관리

힙과 스택, 그리고 변수

 

지역 변수 (stack에 할당)

  • 함수 내에서, 혹은 블록 내에서만 사용할 수 있는 변수
  • 함수가 호출되면서 함수 내부에 선언되었을 때, 그 함수가 return으로 종료될 시, 이 지역변수를 포함하고 있는 stack frame도 return 하게 되어 더 이상 사용 불가

heap에 할당된 변수

  • new나 malloc등의 동적 할당 함수로 heap에 할당된 변수
  • 명시적으로 메모리 할당 해제하지 않는 이상 해제되지 않음 => 메모리 누수가 발생할 수 있음 (주의)
  • 함수가 종료되어도 계속 남아있음

Stack Overflow?

 

이제 가끔씩 프로그램 실행 중 발생할 수 있는 스택 오버프로우 문제가 무엇인지 알 수있다.

말 그대로 매우 많은 함수 호출 등의 스택 영역에 할당한 메모리 크기를 넘어갈 때 발생하는 오류이다.

 

재귀함수에서 함수가 함수를 다시 호출 시에, stack에 함수 호출 정보가 쌓이게 된다.

이 호출이 무한히 또는 매우 많이 이어지면 할당되어 있는 stack 크기를 넘게 된다. 

이 때 발생하는 문제가 스택 오버 플로우이다.


Summary


함수 호출 과정 확인하기

https://minttea25.tistory.com/106

 

함수 호출 in stack

먼저 메모리의 구조는 다음과 같다는 것을 확인하고 넘어가자. stack에는 지역변수와 함수 호출 정보가 저장되어 있고 스택의 자료구조로 되어 있다. 여기서 함수 호출 정보가 무엇을 의미하는지

minttea25.tistory.com

 

'etc' 카테고리의 다른 글

[C++, C#, Java] 소켓 (Socket)  (0) 2023.07.02
함수 호출 in stack  (0) 2023.06.25
Event Bus Pattern [이벤트 버스 패턴]  (0) 2023.06.18
Command Pattern [커맨드 패턴]  (0) 2023.06.18
Observer Pattern [관찰자 패턴]  (0) 2023.06.11