티스토리 뷰

개발하다 보면, 앱을 오래 실행할수록 점점 느려지는 경우가 있다.
"이상하다, 분명 다 썼던 객체들인데 왜 메모리가 줄어들지 않지?"
이럴 때 의심해야 할 것 중 하나가 바로 메모리 누수(Leak)다. 그럼 Swift에서는 이런 문제가 없을까?
다행히도 Swift는 ARC(Automatic Reference Counting)라는 강력한 메모리 관리 시스템을 제공한다.
덕분에 우리는 직접 메모리를 해제할 필요 없이, Swift가 자동으로 알아서 해제해 준다! 

하지만 ARC가 있다고 해서 메모리 누수가 100% 방지되는 건 아니다.
오히려 ARC의 동작 방식을 모르면 앱이 점점 느려지고 크래시까지 날 수 있다.

그렇다면, ARC는 정확히 어떻게 동작할까?
그리고 실무에서는 어떤 점을 조심해야 할까?
오늘 제대로 정리해보자


 ARC란? Swift는 어떻게 메모리를 관리할까?

다른 언어(Java, Python)에서는 GC(Garbage Collection, 가비지 컬렉션)
주기적으로 불필요한 객체를 정리해 준다.

그런데 Swift에서는 GC가 없다.
그럼 "Swift에서는 객체를 언제 해제해야 할까?"

Swift에서는 ARC를 사용해서 객체의 메모리를 자동으로 관리한다.

 

ARC의 핵심 개념

  • 객체는 참조(reference)카운트(Counting)한다.
  • 해당 객체를 참조하는 변수가 하나라도 남아 있으면 해제되지 않는다.
  • 모든 참조가 사라지면, 자동으로 메모리에서 해제된다.

한마디로, ARC는 객체가 필요 없어지는 순간을 계산해서, 알아서 정리해 준다!


ARC는 어떻게 동작할까? 

이해하기 쉽게, ARC가 동작하는 과정을 코드로 살펴보자.

class Person {
    let name: String
    init(name: String) {
        self.name = name
        print("\(name) 객체 생성됨")
    }
    deinit {
        print("\(name) 객체 해제됨")
    }
}

var person1: Person? = Person(name: "Alice") // 참조 카운트: 1
person1 = nil // 참조 카운트: 0 -> 객체 해제

 

출력 결과

Alice 객체 생성됨  
Alice 객체 해제됨

 Person(name: "Alice") 가 생성될 때 참조 카운트가 1 증가한다.
 person1 = nil 이 되면서 참조 카운트가 0이 되고, 객체가 해제된다.

 

이처럼 ARC는 객체를 참조하는 변수가 없을 때 자동으로 메모리를 정리해 준다.
그럼, 문제가 생기는 경우는 언제일까?


ARC의 함정 – 강한 참조 순환(Strong Reference Cycle) 문제

ARC가 있다고 해서, 모든 메모리 문제가 자동으로 해결되는 건 아니다.
오히려 ARC를 제대로 이해하지 않으면 "메모리 누수"가 발생할 수도 있다.

 

⚠️ 강한 참조 순환이란?

객체들이 서로를 참조하면, ARC가 참조 카운트를 0으로 만들지 못해서 객체가 해제되지 않는 문제가 생긴다.

class Person {
    let name: String
    var friend: Person? // 다른 객체를 참조하는 속성
    init(name: String) { self.name = name }
    deinit { print("\(name) 해제됨") }
}

var alice: Person? = Person(name: "Alice")
var bob: Person? = Person(name: "Bob")

alice?.friend = bob
bob?.friend = alice

alice = nil // ❌ 여전히 Bob이 Alice를 참조하고 있음
bob = nil   // ❌ 여전히 Alice가 Bob을 참조하고 있음

결과: 객체가 해제되지 않음 (메모리 누수 발생)


alice와 bob이 서로를 강하게 참조하고 있어서, 참조 카운트가 0이 되지 않아 메모리가 해제되지 않는다! 

이게 바로 "강한 참조 순환(Strong Reference Cycle)" 문제다.
그럼, 어떻게 해결해야 할까?


강한 참조 순환을 해결하는 방법

강한 참조 순환을 해결하려면 weak(약한 참조)나 unowned(비소유 참조)를 사용해야 한다.

 

✅ weak(약한 참조) 사용하기

weak을 사용하면 ARC가 강한 참조를 만들지 않고, 참조 카운트를 증가시키지 않는다.

class Person {
    let name: String
    weak var friend: Person? // weak 키워드 사용
    init(name: String) { self.name = name }
    deinit { print("\(name) 해제됨") }
}

var alice: Person? = Person(name: "Alice")
var bob: Person? = Person(name: "Bob")

alice?.friend = bob
bob?.friend = alice

alice = nil // Alice 해제됨
bob = nil   // Bob 해제됨

이제 객체가 정상적으로 해제된다!!

 

weak을 사용하면 ARC가 이 변수를 참조 카운트 계산에서 제외한다.
한쪽이 weak이면 객체가 사라질 때 자동으로 nil이 된다.


정리 – ARC를 이해하면 더 안정적인 앱을 만들 수 있다

Swift의 ARC(Automatic Reference Counting)
GC 없이도 메모리를 자동으로 관리하는 강력한 시스템이다.
덕분에 개발자가 직접 free() 같은 메모리 해제 작업을 하지 않아도 되고, 빠르고 효율적인 메모리 관리가 가능하다.

하지만! ARC도 완벽한 건 아니다.
강한 참조 순환이 발생하면 메모리 누수가 생길 수 있다.
이럴 때는 weak(약한 참조)과 unowned(비소유 참조)를 적절히 활용해서 해결해야 한다.

 

📌 ARC 핵심 요약

✅ ARC는 참조 카운트를 기반으로 메모리를 자동 관리한다.
✅ 모든 참조가 사라지면 객체는 자동으로 해제된다.
✅ 강한 참조 순환(Strong Reference Cycle) 문제를 조심해야 한다.
✅ weak(약한 참조)와 unowned(비소유 참조)를 활용하면 메모리 누수를 방지할 수 있다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/04   »
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
글 보관함