본문 바로가기
Swift/기본

메모리 구조 (Code, Data, Stack, Heap)

by 밤새는탐험가 2024. 4. 18.

메모리 구조

프로그램이 실행되면, 운영체제는 메모리(RAM)에 프로그램을 위한 공간을 할당한다. 

이 공간은 총 4가지로 Code, Data, Heap, Stack으로 구성되어 있다. 

 

 

✅ 코드 영역

우리가 작성한 소스 코드가 기계어 형태로 저장된다. 

컴파일 타임에 결정되고, 중간에 코드가 변경되지 않도록 Read - Only 형태로 저장된다.

 

기계어란, 컴퓨터가 읽을 수 있는 가장 밑단의 언어로 0, 1로 이루어진 언어이다. 

 

 

✅ 데이터 영역

전역변수, static 변수가 저장된다. 

프로그램 시작과 동시에 종료 되어야 메모리가 해제된다. 

 

실행 도중 변수 값이 변경될 수 있으니 Read - Write로 지정된다.

 

struct Korean {
    static let country = "Korea"     // 스태틱 변수(상수)로 데이터 영역에 할당 
}

var name: String?    // 전역 변수로 데이터 영역에 할당
var age: Int?        // 전역 변수로 데이터 영역에 할당

func fetchData() {
}

 

✔ 스위프트에서 static은 기본 동작이 lazy이다. 

스위프트에서 static인 경우에는 프로그램 시작과 동시에 할당되어 메모리에 올라가지 않고, 

해당 값에 처음 접근할 때 값이 할당되어 메모리에 올라간다.??

 

 

✅ 힙 영역

프로그래머가 할당/해제 하는 메모리 영역이다. 

사용하고 난 후에는 반드시 메모리 해제를 해줘야 한다. 그렇지 않으면 메모리 누수가 발생한다. 

 

Code, Data, Stack 중 유일하게 런타임 시에 결정되기 때문에 

데이터의 크기가 확실하지 않을 때 사용한다. 

 

✔ 클래스 인스턴스, 클로저 같은 참조 타입의 값들은 모두 힙(Heap)에 자동 할당된다. 사용하고 난 후에 "메모리 해제"를 해줘야 하는데, 스위프트는 ARC를 통해 할당된 메모리가 자동으로 해제된다. 

 

 

✅ 스택 영역

함수 호출 시 함수의 지역변수, 매개변수, 리턴 값 등등이 저장되고, 

함수가 종료되면 저장된 메모리도 해제된다. 

 

컴파일 타임에 결정되기 때문에 무한히 할당할 수 없다.

✔ 스택은 프로그램이 자동으로 사용하는 임시 메모리 영역이다. 

 

func add(_ a: Int, _ b: Int) -> Int {   // 파라미터 a, b는 스택에 할당된다.
    let result = a + b                  // 지역변수 result는 스택에 할당된다.
    return result
}

 

우리가 위에 처럼 그냥 함수를 호출하면 운영체제는 내부적으로 함수 안에 선언된

파라미터, 지역변수 등을 스택에 할당한다. 

 

위에 add 함수가 종료되는 시점에 스택에 저장된 메모리는 모두 해제된다. 

 

스택은 "LIFO"로 먼저 생성된 변수가 나중에 해제된다.

 

✔ 스택은 메모리 크기에 대한 제한이 있기 때문에, 메모리를 무한히 할당할 수 없다. 

 

 

 

⭐ 힙 VS 스택 ⭐

✅ 언제 힙을 쓰고, 스택을 쓰나?

스택은 메모리가 한정되어 있기 때문에 너무 큰 메모리는 할당할 수 없다. 

데이터의 크기를 모르거나, 스택에 저장하기엔 큰 데이터의 경우에는 힙에 할당된다. 

 

그 외에는 스택에 할당한다. 

✔ 스택에 너무 많은 메모리를 할당하게 되면 "스택 오버 플로우"가 발생한다.

 

✅ 힙과 스택의 메모리 관계 

힙과 스택은 같은 메모리 영역을 공유한다. 

 

같은 메모리 공간이지만, 힙 영역은 낮은 메모리 주소부터 할당 받고,

스택 영역은 높은 메모리 주소부터 할당 받는다. 

 

힙도 스택처럼 많은 메모리를 할당하게 되면 "힙 오버 플로우"가 발생한다.

 

 

'Swift > 기본' 카테고리의 다른 글

ARC 2편 - 강한 참조 순환  (0) 2024.04.19
ARC 1편 - ARC 란?  (0) 2024.04.19
접근 제어자 (Access Control)  (0) 2024.04.17
서브스크립트  (1) 2024.04.16
제네릭 (제네릭 제약, 제네릭 확장, 제네릭 함수와 오버로딩)  (0) 2024.04.16