Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ARC (strong , weak, unowned, 순환 참조) 1 #21

Closed
kimkyuchul opened this issue Dec 29, 2022 · 0 comments
Closed

ARC (strong , weak, unowned, 순환 참조) 1 #21

kimkyuchul opened this issue Dec 29, 2022 · 0 comments

Comments

@kimkyuchul
Copy link
Owner

kimkyuchul commented Dec 29, 2022

들어가기 앞서 Heap과 Stack

Heap

  • 프로그래머가 할당/해제 하는 메모리 영역
  • 사용하고 난 후 반드시 메모리 해제를 해줘야 함 → 그렇지 않으면 memory leak 발생
  • 메모리(RAM)공간 4가지(Code, Data, Stack, Heap) 중 유일하게 런타임 시 결정되기 때문에 데이터의 크기가 확실치 않을 때 사용
  • Swfit 기준으로 Heap에 할당되는 것은 클래스 인스턴스, 클로저 같은 참조 타입의 값 → 얘네는 힙에 자동 할당 됨
    • Value Type: Structure, Enumeration, Tuple
    • Reference Type: Class, Closure
  • 힙을 사용하고 나면 반드시 "메모리 해제"를 해줘야함 → Swift에서는 ARC를 통해 힙을 자동 해제해줌!

Stack

  • 함수 호출 시 함수의 지역변수, 매개변수, 리턴 값 등이 저장되고, 함수가 종료되면 저장된 메모리도 해제
  • 컴파일 타임에 결정되기 때문에 무한히 할당 X
  • 스택은 임시 메모리 영역이라고 볼 수 있음
func greeting(_ friend: Int, _ me: Int) -> Int { // 파라미터 2개는 스택에 할당
		let result = friend + me // 지역변수 result는 스택에 할당
    return result
}
  • 함수 안에 선언된 파라미터, 지역변수 등을 스택에 할당
  • 그리고 위 함수가 종료되는 시점에 스택에 저장된 모든 메모리를 반환
  • "LIFO"(last in, first out) 데이터 구조 (먼저 생성된 변수가 가장 나중에 해제됨) → 속도가 빠름
  • 스택은 메모리 크기에 대한 제한이 있음 → 너무 많은 메모리를 스택에 할당하면 스택 오버 플로우 발생

Heap vs Stack

  • 데이터의 크기를 모르거나 스택에 저장하기 큰 데이터일 시 → Heap 할당
  • 그 외엔 Stack에 할당
  • 사실 Heap과 Stack은 같음 메모리 영역을 공유 → 힙 영역은 낮은 메모리 주소부터 할당, 스택 영역은 높은 메모리 주소부터 할당

ARC?

  • Automatic Reference Counting의 약자, Swift의 메모리 사용량 추적 및 관리 시스템
  • ARC는 더이상 필요하지 않은 클래스 인스턴스를 자동으로 메모리에서 해제
  • 위에서 Heap과 Stack을 알아봤듯이 스택은 함수가 종료되면 메모리가 자동으로 반환되는 것 처럼 특별한 관리가 필요 없음
  • 그러나 힙 메모리에 저장된 데이터는 참조(reference) 타입이므로, 개발자가 동적으로 관리해야함 → 참조 타입의 경우 인스턴스가 참조를 통해 여러 곳에서 접근하므로 언제 메모리가 해제되는지가 중요
  • 따라서 힙에 저장된 데이터를 관리할 도구가 필요(인스턴스, 클로저 등등 참조 타입(Reference Type)은 자동으로 힙에 할당) → ARC를 사용

ARC의 메모리 관리 방법

  • ARC가 나오기 전 수동으로 메모리 관리를 하는 MRC(Manual Reference Counting)를 활용했는데, 개발자가 직접 retain과 release를 호출하며 메모리를 관리하는 코드를 작성 해야 했음
    • retain: 객체의 reference count(retain count)를 증가시킨다. → 객체가 메모리에서 해제되지 않도록 이 함수를 호출하여 카운트를 증가
    • release: 객체의 reference count(retain count)를 감소시킨다. → 객체를 더이상 필요하지 않을 때, 이 함수를 호출하여 카운트를 감소 시킴
  • 하지만 ARC는 컴파일러가 자동으로 메모리 관리 코드를 넣어준다.
  • 즉, ARC는 retain, release의 호출을 통해 메모리 관리를 수행 → 이러한 메모리 관리 방법을 Reference Counting(Retain Counting)*=이라고 한다!

RC(Reference Counting)

  • 메모리의 참조 횟수(RC)를 계산하여, 참조 횟수가 0이 되면 더 이상 사용하지 않는 메모리라 생각하여 해제
  • 만약 참조 횟수가 5면 10군데에서 참조하고 있다는 뜻이고, 참조 횟수가 0이면 아무데서도 참조되지 않으니 메모리를 해제하라는 뜻
  • 인스턴스는 하나 이상의 소유자(Owner)가 있는 경우 메모리에 유지
    • 클래스 인스턴스를 변수에 저장하면 변수가 소유자가되고 이 때 참조 카운트는 1이 증가
    • 마찬가지로 또 다른 변수에 저장하면 2가 됨 → 해당 인스턴스의 retain 메소드를 호출 하는 것과 같음
  • 인스턴스가 더 이상 필요하지 않다면 소유권을 포기해야하고 이것은 release 메소드와 같음
    • release 하면 참조 카운트가 1 감소. → 결국 0이 되면 즉시 메모리에서 제거

Count Up

  • 인스턴스를 새로 생성할 때
  • 기존 인스턴스를 다른 변수에 대입할 때

Count Down

  • 인스턴스를 가리키던 변수가 메모리에서 해제되었을 때
  • nil이 지정
  • 변수에 다른 값을 대입
  • 프로퍼티의 경우, 속해 있는 클래스 인스턴스가 메모리에서 해제될 때

참고자료

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant