iOS 개발/iOS

[iOS] 메모리 구조

도지대디 2022. 7. 12. 00:14

[iOS] 메모리 구조

프로그램이 실행되면 OS 는 메모리에 프로그램을 위한 공간을 할당해줍니다. 

 

메모리는 크게 4가지 영역으로 나뉘어져 있는데, 이는 각각 코드 영역, 데이터 영역, 힙 영역, 스택 영역이라고 불립니다.

 

코드 영역

  • 소스코드가 기계어 형태로 저장됨
    • 컴퓨터가 읽을 수 있는 가장 밑단의 언어로 binary 하게 이루어짐 (0, 1)
  • 컴파일 타임에 결정되고, 중간에 코드가 변경되지 않도록 Read-Only 형태로 저장됨

 

코드 영역은 말 그대로 프로그램의 소스코드를 기계어 형태로 저장하는 영역입니다.

 

프로그램이 실행되며 소스코드가 변경되면 안되기 때문에 Read-Only 형태로 저장됩니다.

데이터 영역

  • 전역변수, static 변수가 저장됨
  • 프로그램 시작과 동시에 할당되며 프로그램이 종료되어야 메모리가 해제됨
  • 실행 도중 변수값이 변경될수도 있으니 Read-Write 로 저장됨

 

데이터 영역에는 전역변수와 static 변수가 저장됩니다. 

 

이는 프로그램 어디에서든 사용될 가능성이 있기 때문에 프로그램 시작과 동시에 할당되고, 프로그램이 종료되어야 메모리가 해제됩니다.

 

또한 변수값이 변경될 가능성이 있기 때문에 Read-Write 로 저장됩니다.

 

코드를 통해 예시를 살펴보겠습니다.

struct SomeStruct {
    static let property = "some property"
}

var number: Int?
var label: String?

여기서 static 상수인 property 와 전역변수인 number, label 은 모두 데이터 영역에 할당됩니다.

힙 영역

  • 사용자에 의해 메모리 공간이 동적으로 할당되고 해제되는 영역
  • malloc, calloc 등으로 힙에 메모리를 할당할 수 있으며 이를 동적할당 이라고 함
    • Swift 에서는 직접 할당하거나 해제할 일이 거의 없음 (ARC 가 관리)
  • 사용하고 난 후에는 반드시 메모리 해제 필요, 그렇지 않으면 메모리 누수 발생
  • 런타임 시 결정되기 때문에 데이터의 크기가 확실하지 않을 때 사용
  • 클래스 인스턴스나 클로저 등 Reference Type 들이 할당됨

 

힙 영역은 사용자에 의해 메모리 공간이 동적으로 할당되고 해제되는 영역으로써, 대부분 클래스 인스턴스나 클로저와 같은 Reference Type 이 할당됩니다.

 

힙 영역에서 사용된 메모리는 반드시 해제가 되어야 하는데, 이는 ARC 가 알아서 관리해주기 때문에 사용자가 직접 해제할 일은 거의 없습니다. 

 

ARC 에 대한 자세한 설명은 아래 링크를 참고하시면 됩니다.

 

[Swift] ARC (1/2)

[Swift] ARC (Automatic Reference Counting) 앱의 메모리 사용량을 추적하고 관리 어떠한 클래스 인스턴스가 더 이상 필요하지 않을 때 인스턴스에 할당된 메모리 자동해제 Reference Type 인 클래스 인스턴스

trumanfromkorea.tistory.com

 

힙 영역의 장점과 단점은 다음과 같습니다.

장점

  • 메모리 크기에 제한 없음
  • 본질적인 범위가 전역이기 때문에 프로그램의 모든 함수에서 접근 가능

단점

  • 할당 / 해제로 인한 속도 저하
  • 힙 손상 (이중해제, 해제 후 접근) 으로 인한 속도 저하
  • 힙 경합 (2개 이상 스레드가 동시에 접근하려 할때 Lock 생기는 현상) 으로 속도 저하
  • 메모리를 직접 관리해줘야 함 (해제해주지 않을 시 메모리 누수)

스택 영역

  • 함수 호출 시 함수의 지역변수, 매개변수, 리턴값 등이 저장되고 함수가 종료되면 저장된 메모리도 해제됨
  • 컴파일 타임에 결정되기 때문에 무한히 할당 불가
  • 스택으로 구성되어있기 때문에 먼저 생성된 변수가 나중에 해제됨 (LIFO)
  • CPU 에 의해 관리되고 최적화되기 때문에 힙보다 속도가 빠름

 

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

 

함수를 호출하면 OS 는 함수 내에 선언된 지역변수, 매개변수 등을 스택에 할당하고 함수가 종료되는 시점에 스택에 저장된 메모리는 모두 알아서 반환됩니다.

 

스택 영역의 장점과 단점은 다음과 같습니다.

장점

  • CPU 가 스택 메모리를 효율적으로 구성하기 때문에 속도가 매우 빠름
  • 메모리를 직접 해제 해주지 않아도 됨

단점

  • 메모리 크기에 제한 있음
  • 지역 변수만 접근 가능
  • 메모리가 한정되어있기 때문에 너무 많은 데이터를 할당하게 되면 Stack Overflow 발생 (무한루프 등..)

힙과 스택의 메모리 관계

앱이 실행되는 동안 이미 작성된 코드나 변수들이 변경될 일은 없기 때문에 코드 영역과 데이터 영역은 메모리 사용량에 변동이 없습니다.

 

하지만 계속해서 인스턴스가 할당, 해제되는 스택 영역과 힙 영역은 메모리 사용량이 가변적입니다.

 

힙 영역과 스택 영역은 메모리 영역을 공유합니다.

 

그래서 인스턴스, 클로저 등 자동으로 힙에 할당되는 것 외에 직접 메모리를 할당할 경우, 데이터의 크기를 모르거나 스택에 저장하기에 큰 데이터는 힙 영역에 할당됩니다.

 

같은 메모리 공간이지만 힙 영역은 낮은 메모리 주소부터 할당받고 스택 영역은 높은 메모리 주소부터 할당받습니다.

 

힙 영역과 스택 영역이 서로의 영역을 침범할 시, Stack Overflow 나 Heap Overflow 가 발생할 수 있습니다.

참고 링크

https://babbab2.tistory.com/25

 

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

안녕하세여~~ 소들입니다 :-))))) 오늘 웬 듣보잡 버그 한 놈이 나왔는데 처음에 메모리 참조 오류인 줄 알고 하루 종일 메모리에 대해서 공부 했는데 버그 원인은 메모리가 아니었음ㅋ (디코딩 네

babbab2.tistory.com

https://sihyungyou.github.io/iOS-Memory-Architecture/

 

iOS) 메모리구조 - Code, Data, Stack, Heap

메모리 구조 이해하기

sihyungyou.github.io