메모리 구조
프로그램이 실행되면 OS는 메모리에 실행한 프로그램을 위해 아래와 같은 공간을 할당해 줌.
메모리 (RAM) |
코드 영역 |
데이터 영역 |
힙 영역 |
스택 영역 |
코드 영역
우리가 작성한 코드가 기계어 형태로 저장 됨.
- 컴파일 타임에 결정 됨.
- Read-Only 형태로 저장 됨.
✅ 기계어 : 컴퓨터가 읽을 수 있는 가장 밑단의 언어. (0과 1로만 이루어져 있음.)
데이터 영역
전역변수, static 변수가 저장 됨.
- 프로그램 시작과 동시에 할당 됨.
- 프로그램이 종료 되어야 메모리가 해제 됨.
- Read-Write로 저장 됨.
struct Seongil {
static let lastName: String = "Yeo"
// static 변수 ➡️ 데이터 영역
}
var address: String // 전역 변수 ➡️ 데이터 영역
var age: Int // 전역 변수 ➡️ 데이터 영역
힙 영역
개발자가 할당/해제하는 메모리 영역
- 런타임 시에 결정 됨. (데이터의 크기가 확실하지 않을 때 사용)
- 개발자는 malloc, calloc으로 힙에 메모리를 할당할 수 있다. (동적 할당)
- 사용하고 난 후에는 반드시 메모리 해제를 해줘야 함. (해제하지 않으면 메모리 누수가 발생하기 때문)
- 메모리 크기에 대한 제한이 없다.
- 전역적인 범위를 갖고있기 때문에, 프로그램의 모든 함수에서 접근할 수 있다.
- 할당 작업, 해제 작업, 힙 손상(이중 해제, 해제 후 사용), 힙 경합(두 개 이상 쓰레드가 동시에 접근하려 할 때 Lock) 등으로 인한
속도 저하가 발생할 수 있다.
- 크기에 제한은 없지만 자신의 영역 외로 확장하려다 보면, 힙 오버 플로우가 발생한다. (스택과 메모리를 공유하기 때문)
스위프트에서는 malloc, calloc 함수를 이용해서 힙 영역에 직접 할당할 일이 별로 없다.
하지만 우리는 무의식적으로 힙에 메모리를 할당하고 있었는데,
스위프트에서는 클래스 인스턴스, 클로저 같은 참조 타입의 값들은 모두 힙에 자동 할당 된다.
힙은 사용하고 난 후 반드시 메모리 해제를 해줘야 한다.
하지만 우리는 여태 클래스 인스턴스를 생성하고 사용하면서 메모리 해제를 해주는 작업을 해온 적이 없다. (적어도 나 같은 경우)
왜냐하면 스위프트는 ARC를 통해 힙에 할당 된 메모리가 더 이상 참조되지 않으면 자동으로 해제해주기 때문이다.
스택 영역
프로그램이 자동으로 사용하는 임시 메모리 영역
- 컴파일 타임에 결정 됨. (무한히 할당 불가)
- 함수 호출 시 함수의 지역변수, 매개변수, 리턴 값 등이 저장되고, 함수가 종료되면 저장된 메모리도 해제한다.
- CPU에 의해 관리되고 최적화 되므로 속도가 빠르다.
- 메모리를 직접 해제 해주지 않아도 됨.
- 메모리 크기에 대한 제한이 있다.
- 지역 변수만 접근 가능하다.
- 스택에 너무 많은 메모리를 할당하게 되면 스택 오버 플로우가 발생한다.
func min(_ a: Int, _ b: Int) -> Int {
let result = a - b
return result
}
✅ min함수의 매개변수 a,b는 스택에 할당된다.
✅ min함수의 지역변수 result는 스택에 할당된다.
✅ min함수의 리턴 값 result는 스택에 할당된다.
우리가 함수를 호출하면 위와 같이 OS는 내부적으로 함수 안에 선언 된 매개변수, 지역변수, 리턴 값 등을 스택에 할당한다.
그리고 위의 min 함수가 종료되는 시점에 저장된 메모리는 해제 된다.
✅ 스택은 LIFO(후입선출)이므로, 먼저 생성 된 변수가 가장 나중에 해제된다.
힙 VS 스택
스택은 메모리 크기에 제한이 있기 때문에 너무 큰 메모리는 할당할 수 없다.
따라서 데이터의 크기를 모르거나, 스택에 저장하기엔 너무 큰 데이터의 경우 힙에 할당하고
그 외엔 스택에 할당하면 된다.
힙과 스택의 관계
힙과 스택은 같은 메모리 영역을 공유한다.
같은 메모리 공간을 공유하지만, 힙 영역은 낮은 메모리 주소부터 할당 받는 것이고, 스택 영역은 높은 메모리 주소부터 할당 받는다.
Reference
https://babbab2.tistory.com/25
https://gangdor.tistory.com/41
'iOS > iOS' 카테고리의 다른 글
[iOS] 네트워크 통신 - URL, URLComponents (0) | 2023.08.12 |
---|---|
[iOS] 네트워크 통신 - URLSession 간단한 예제 (0) | 2023.08.10 |
[iOS] 네트워크 통신 - URLSession (LifeCycle, GET/POST) (0) | 2023.08.10 |
[iOS] 네트워크 통신 - URLSession (URLSessionConfiguration, URLSessionTask) (0) | 2023.08.10 |
[iOS] 2. 메모리 관리 1 - ARC (Automatic Reference Counting) (0) | 2023.08.03 |