티스토리 뷰
복습) 값 형식과 참조 형식 (711)
- 값 형식 (Value Type)
- Baisic Type, 튜플, 구조체, 열거형, 컬렉션 등이 해당된다.
- Stack 영역에 값이 저장된다.
- 필요시에는 항상 메모리의 값이 복사되어 전달된다.
- 사용이 끝나면, Stack프레임에서 알아서 제거되므로 별도로 메모리 관리를 할 필요 없다.
- 참조 형식 (Reference Type)
- 클래스, 클로저가 해당된다.
- 필요시에 항상 메모리의 주소를 전달한다. (Heap의 주소를 Stack에 저장)
- Heap 영역에 실제 값들이 저장된다.
- **RC(Reference Counting, 참조 카운팅)**을 통해 메모리를 관리한다.
- Swift에서 사용하는 ARC 모델
복습) 메모리 구조 - 코데힙스
- 코드영역
- CPU가 실행할 수 있는 실질적 명령어들이 모여있는 공간 (모든 코드, 프로그램이 존재)
- get Only
- 코드영역에 필요한 데이터들이 데이터, 힙, 스택 영역에 저장되어있다.
- 데이터 = 전역 변수, 타입 속성 등 공통으로 공유되는 데이터
- 힙 = 동적할당으로 크기가 크고, 관리할 필요가 있는 데이터
- 스택 = 함수 실행을 위한 임시 공간
- 데이터 영역
- 공통으로 공유하기 위한 데이터를 저장한다.
- 전역 변수, 타입속성을 저장한다.
- 붕어빵 틀이 저장되어 있다.
- 앱이 실행되는 동안은 불변의 성질을 갖는다.
- 공통으로 공유하기 위한 데이터를 저장한다.
- 힙 영역
- 인스턴스를 동적으로 할당한다. (동적할당)
- 일반적으로 긴 시간동안 저장한다.
- 필연적으로 느릴 수밖에 없다.
- 관리하지 않으면 메모리 누수 현상이 발생해 앱이 종료될 수 있다.
- 메모리 누수 현상(Memory Leak): 메모리가 제거되지 않는 현상
- 개발자가 직접 관리해주어야한다.
- 인스턴스를 동적으로 할당한다. (동적할당)
- 스택 영역
- 함수 실행을 위한 임시적 공간이다.
- 크기가 작고 빠르게 사용하기 위한 데이터가 저장되어 있다.
- 자동으로 메모리 관리가 이루어진다.
언어 별 메모리 관리 기법
- 자바의 GC (Garbage Collector)
- 런타임에 힙 영역을 자동으로 스캔해서 알아서 관리해줌
- 스캔하는 속도가 있어서 느려짐! (언제 어느 시점에 이루어지는지는 알 수 없음)
- objective - c
- 참조 숫자(RC)를 세는 것을 통해 메모리 관리 / 컴파일 시 메모리 해제시점 결정
- 수동으로 숫자 세는 것이 MRC (개발자가 수동으로 계산)
- 자동으로 숫자 세는 것이 ARC
- 컴파일러가 알아서 코드를 심어줌메모리 해제가 잘 되도록, 이론을 잘 알고 사용해야함.
- → 메모리 관리를 알아서 해주는게 아니고 숫자를 제대로 세 준다는것임!
- Swift
- ARC (Automatic RC)
- 메모리를 수동으로 관리할 수 없다.
- ARC (Automatic RC)
ARC 작동 원리
- 클래스의 인스턴스가 생성될 때마다 ARC는 인스턴스에 대한 정보를 저장한다.
- 인스턴스, 관련 프로퍼티 값, 인스턴스 타입에 대한 정보를 저장한다.
- 인스턴스가 더이상 필요하지 않으면, ARC는 사용된 메모리를 할당 해제한다.
- 인스턴스에 참조가 하나라도 존재한다면, ARC는 메모리를 할당 해제하지 않는다.
- → 이를 위해 클래스 인스턴스를 할당할 때마다 강한 참조를 만들게 된다. 참조는 해당 인스턴스를 유지하고, 강한 참조가 남아있는 한 할당 해제를 허용하지 않기 때문에 강한 참조라고 부른다.
- → 클래스 인스턴스가 필요하지 않을 때 메모리 공간을 차지하지 않는다.
ARC와 MRC
1. ARC
class Point {
var x, y: Double
func draw() {}
}
let point1 = Point(x: 0, y: 0)
let point2 = point1
point2.x = 5
//use point1
//use point2
2. MRC
class Point {
**var refCount: Int**
var x, y: Double
func draw() {}
}
let point1 = Point(x: 0, y: 0)
let point2 = point1
**retain(point2)**
point2.x = 5
//use point1
**release(point1)**
//user point2
**release(point2)**
- 이전 언어들은 MRC와 같이 메모리를 수동으로 관리했다.
- 현대 언어의 경우 자동 메모리 관리 모델을 사용한다.
- 컴파일러가 retain() ⇒ release() 해제 코드를 삽입한다고 생각
- 이전 언어들은 메모리를 수동 관리했음 (MRC)
- 현대 언어의 경우 자동 메모리 관리 모델 사용
- Swift는 컴파일러가 retain()할당 코드 → release() 해제 코드를 삽입한다
- 메모리 관리에 대한 실수를 방지하여 프로그램의 안정성이 증가된다.
ARC 기반
- 나를 가리키는 소유자가 없으면 해제된다는 원칙을 가지고 있다.
- 소유 정책
- 하나 이상의 소유자가 있는 경우 메모리에 유지됨
- 참조 카운팅
- 나를 가리키는 소유자 카운팅
ARC 동작
- 어떻게 자동 참조 카운팅이 동작하는가?
class Person {
let name: String
init(name: String) {
self.name = name
print("\\(name) is being initialized")
}
deinit {
print("\\(name) is being deinitialized")
}
}
var soi: Person? = Person(name: "지원") // retain(soi), RC: 1
var reference: Person?
var reference = Person(name: "John") // retain(reference), RC: 2
soi = nil // release(soi), RC: 1
reference = nil // release(reference), RC: 0
- 예전 언어의 경우 모든 메모리를 개발자들이 수동 관리했다. (retain, release)
- 현대적 언어는 대부분 자동 메모리 관리 모델을 사용하며, Swift의 경우 컴파일러가 retain() → release()코드를 삽입한다고 보면된다.
- 프로그램 메모리 관리에 대한 안정성이 증가했다.
GitHub - JIWON1923/Today-I-Learend
Contribute to JIWON1923/Today-I-Learend development by creating an account on GitHub.
github.com
앨런님의 Swift 강의 및 애플 공식 문서를 보며 작성한 글입니다.
'Swift > Swift 문법' 카테고리의 다른 글
[Swift] 에러처리, (feat 피보나치수열) (0) | 2023.01.02 |
---|---|
[고차함수 5] forEach, compactMap, flatMap (0) | 2022.12.29 |
[고차함수 4] reduce (0) | 2022.12.29 |
[고차함수 3] filter (0) | 2022.12.29 |
[고차함수 2] Map (0) | 2022.12.29 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- replit
- 시간초과
- 부르트포스
- Swift
- 설명
- 정답
- 16진수 입력
- ord
- python
- 반복문
- 리플릿
- 깃
- 레플릿
- 깃허브
- 코드 업
- CodeUp
- Code up
- for문
- do while
- 이것이 코딩테스트다
- COMMIT
- level1
- 코드업
- baekjoon
- SwiftUI
- 파이썬
- 기초 100제
- 백준
- CHR
- 프로그래머스
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
글 보관함