힙 메모리를 관리하는 방법은 두 가지가 있습니다.
GC(Garbage Collection)와 RC(Reference Count)가 있습니다.
JAVA(AOS)에서는 GC를 사용하고 Swift(iOS)에서 RC를 사용합니다.
GC와 RC 모두 사용하지 않는 객체를 해제하기 위한 수단입니다. 하지만 둘의 동작방식에 차이가 있습니다.
이제부터는 조금은 복잡한 이야기를 하려고 합니다!
ARC는 RC(Reference Count)로 메모리의 참조 카운트를 통해 메모리를 관리한다고 했었습니다.
예제를 보면서 설명하겠습니다.
인스턴스의 주소값을 변수에 할당하게 될 때 참조 카운트가 올라가게 됩니다.
class Person {
let name: String
init(name: String) {
self.name = name
print("init")
}
deinit {
print("deinit")
}
}
var hoBahk = Person(name: "Hohahk") // RC +1, Instance RC: 1
var hoBahk2 = hoBahk // RC +1, Instance RC: 2
var hoBahk3 = hoBahk // RC +1, Instance RC: 3
처음에 Person의 새로운 인스턴스인 hoBahk 인스턴스를 만들었을 때 RC가 1 증가합니다.
그리고 hoBahk인스턴스를 hoBahk2라는 변수에 대입할 때 RC가 또 1 증가하게 되어 RC가 2가 됩니다.
hoBahk3에도 Person의 인스턴스를 할당하게 되면 RC 1이 또 증가하기 떄문에 RC가 3이 됩니다.
RC가 감소할 때 예제를 보겠습니다!
1. 인스턴스에 nil을 할당 할 때 RC가 감소하게 됩니다.
class Person {
let name: String
init(name: String) {
self.name = name
print("init")
}
deinit {
print("deinit")
}
}
var hoBahk: Person? = Person(name: "Hohahk") // RC +1, Instance RC: 1
var hoBahk2 = hoBahk // RC +1, Instance RC: 2
hoBahk = nil // RC -1 , Instance RC: 1
hoBahk2 = nil // RC -1 , Instance RC: 0 (메모리 해제)
2. 인스턴스를 할당한 변수에 다른 값을 할당하게 되면 해당 인스턴스의 RC는 감소합니다.
var hoBahk: Person = Person(name: "Hohahk") // hoBahk Instance RC 1
var lisa = Person(name: "lisa") // lisa Instance RC 1
hoBahk = lisa // hoBahk Instance RC 0(메모리 해제), lisa Instance RC 2
3. 인스턴스를 가리키던 변수가 메모리에서 해제어도 RC는 감소합니다.
func makeClonePerson(_ person: Person) {
// 함수 내부에 들어온 당시에는 변수 clone에도 인스턴스 person을 할당하기 때문에 RC가 1 증가하여 2가 된다.
let clone = person // Instance RC: 2
// 함수를 나가게 되면 변수는 clone은 메모리에서 해제 되기 때문에 RC가 1 감소하여 1이 된다.
}
var hoBahk: Person = Person(name: "Hohahk") Instance RC: 1
makeClonePerson(hoBahk) Instance RC: 1
4. 다른 클래스의 프로퍼티로 속해 있을 때, 해당 클래스의 인스턴스가 메모리에서 해재될 때 RC가 감소하게됩니다.
class Person {
let name: String
let physicalSize = PhysicalSize(height: 180.3, weight: 75.1)
init(name: String) {
self.name = name
}
deinit {
print("deinit")
}
}
class PhysicalSize {
let height: Double
let weight: Double
init (height: Double, weight: Double) {
self.height = height
self.weight = weight
}
deinit {
print("deinit")
}
}
var hoBahk: Person? = Person(name: "Hohahk")
hoBahk = nil // Person, PhysicalSize 모두 deinit
먼저 GC, RC에 대해 알아보고 ARC의 동작 방법에 대해서 알아보았습니다.
다음에는 ARC의 문제졈인 순환참조에 대해서 알아보겠습니다..!
감사합니다~