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

Memory Value type vs Reference type #110

Closed
Youngminah opened this issue Jan 10, 2022 · 0 comments
Closed

Memory Value type vs Reference type #110

Youngminah opened this issue Jan 10, 2022 · 0 comments

Comments

@Youngminah
Copy link
Owner

Youngminah commented Jan 10, 2022

Type in Swift

  • 스위프트의 타입은 크게 두 카테고리로 나뉩니다.
  • Value Type (값타입)

    • struct, enum, tuple
    • 스위프트 기본형 타입 Int, Float, Double, Bool, String, Array, Dictionary, Set등 (stuct으로 구현되어있음)
    • data의 unique한 복사본을 생성함.
    • Reference Counting 개념을 사용하지 않는다!! - Retain count를 증가시키지 않는다.
    • 복사본에 관한 수정은 다른 변수에 영향을 주지 않는다.
  • Reference Type (참조타입)

    • class, function, closure
    • shared instance 를 사용
    • 같은 참조를 가지는 변수에 관한 수정은 다른 변수에 대하여 영향을 준다.


어떤한 경우 적합할까? ⭐️ (쉬운내용이니 차근차근 읽어보기)

  • 기본적으로 값타입 보다 참조타입이 성능적으로 추적에 대한 비용이 많이 들고, 값 타입은 리소스가 적게든다.
  • Reference Type 보다 Value Type을 선택하는 주된 이유 중 하나는 성능말고도 의도치 않은 데이터의 변경을 방지 할 수 있다.
  • 값 타입은 복사된 유니크한 instance를 얻을 수 있기 때문에, 다른부분에서 해당 데이터를 변경하지 않는다는 것을 보장받을 수 있다.
  • 변경하려고 하면 새로운 유니크한 인스턴스가 복제된 이후 이것이 변경될 것이기 때문, 즉 메모리의 주소값 공유 안함.
  • 조금 더 , 실무적인 이야기로는 다른 스레드에서 데이터를 변경할 수 있는 다중 스레드 환경에서 유용하다.
  • 즉, Thread간 의도하지 않은 공유로부터 안전하다.
  • (다중 스레드 환경에서 동일한 데이터를 변경하는 것은 디버그하기 굉장히 어려운 상황을 야기할 수 있다.)


Type에 따른 메모리 할당 공간

image

  • 운영체제를 공부하다보면 위와 같은 메모리 구조를 한번쯤은 봤을 것이다.
  • 이쯤에서 Swift의 스택, 힙에 관한 내용을 정리해보자
  • Stack

    • 스택은 정적 메모리 영역으로 컴파일 타임에 결정된다.
    • 빠른 접근이 특징
    • 스택은 크기가 변하는 객체와 함께 사용되지 않는다.
    • 값 타입 중에 크기가 컴파일 시간에 결정될 수 있거나 참조 유형을 포함하지 않는다면 스택할당으로 이루어진다.
  • Heap

    • 힙은 동적 메모리 영역으로 런타임에 결정된다.
    • 참조 시간, 할당/해제 비용 때문에 비교적 느린 접근이 특징.
    • 힙은 모든 사람들과 공유된다 !!
    • 값 타입중 크기가 컴파일 시간에 결정될 수 없는 경우, 참조유형에 포함된 경우 힙 영역에 저장.

  • 일반적으로 생각하면 값타입 -> Stack영역 , 참조타입 -> Heap영역 1:1 매칭이라고 생각할 것이다.
  • 하지만, 꼭 그런것은 아니다. ❗️❗️ 중요 ❗️❗️
  • 값타입이 힙에, 참조타입이 스택에 저장될 때가 있다.
  • 즉, Type에 따른 저장 공간이 상황에 따라 달라질 수 있다는 것이다.

image



Value Type이 Heap 메모리에 할당되는 경우

  • 값 유형은 수명이 짧은 경우 스택에 저장될 수 있으며, 수명이 긴 경우 힙에 저장될 수 있다.❗️❗️
  • 또한, 값 타입이 클래스의 일부인 경우 힙메모리 내부에 저장될 수 있다.
  • 또한, 값 타입이 컴파일 시간동안 결정될 수 없는 경우 ( 프로토콜/ 일반 요구사항 등 때문에) 힙 할당이 이루어질 수 있다.
  • Array, Dictionary, Set, String(collection of characters)과 같은 가변 길이 Collection들은
  • 일반적으로 내부 데이터를 Heap 에 저장해서 사용된다.
  • 상황에 따라 값 타입 자체가 스택에 저장되기도 한다.
  • Array, String 등은 기본적으로 struct로 구현된 값 타입이기 때문에 인스턴스마다 유니크한 데이터를 가져야 한다.
  • 하지만 매번 새로운 공간을 할당하고 복사하는 것은 부담이 있고, 특히 데이터가 거질 수록 부담은 커질것이다.
  • 이러한 문제를 해결하기 위해 컬렉션은 Copy-On-Write: COW라는 기법을 사용한다.
  • Copy-On-Write: COW
    • 값을 새로운 변수에 할당할 때 바로 복사본을 만드는 것이 아니라, 수정할 때 복사본을 만드는 기법이다.
    • 수정 전까지는 기존 element가 저장된 메모리 주소를 참조하는 공유 방식을 사용하는 것임.


Reference Type값이 Stack 메모리에 할당되는 경우

  • 참조 타입의 사이즈가 고정되어 있거나 , 라이프 타임을 통해 예측할 수 있는 경우
  • 즉, SIL에 의해 (추후설명) 컴파일 타임에 결정 할 수 있는 경우 스택에 할당 할 수 있다.


Swift Intermediate Language (SIL)

스위프트의 최적화, 분석과 관련된 하이레벨 중간 언어이다.

  • SIL이란 Swift Intermediate Language의 약자로, Swift의 소스 코드를 실행 가능한 바이너리 코드로 바꿀 때, 다른 컴파일러(LLVM)가 취급하기 쉬운 중간표현(Intermediate Representation)으로 변환한 코드를 말함.
  • Swift의 컴파일러는 LLVM을 통해서 바이너리 코드를 생성하는데,
  • 바이너리 코드를 생성하는 과정에서 LLVM을 위한 중간표현인 LLVM IR을 생성하게 되고, SIL은 Swift 코드와 LLVM IR과의 중간에 위치


요약

  • Stack 영역에 할당되는 객체는 크기가 변화할 수 업어야 하며, 공유되지 않으므로 컴파일 타임에 결정된다.
  • Heap 영역에 할당되는 객체는 변화할 수 있고, 공유되므로 런타임에 결정된다.
  • 값타입 -> Stack영역 , 참조타입 -> Heap영역 이다는 더이상 틀린 말❗️이다.
  • 참조타입이 스택영역에 할당되는 것은 SIL에 의한 승격화로 이루어 진다.
  • Collection Type(값타입) 중에 가변길이를 가지는 타입들은 일반 적으로 힙영역에 저장되서 사용되며
  • COW 방식을 이용하여 수정할 때 복사본으로 스택 메모리 영역에 할당 된다.




참조

Value type vs Reference type in Swift
Medium - Swift의 Type과 메모리 저장 공간
Medium - Swift의 메모리 관리(Heap, Stack, ARC)
Value Types and Reference Types in Swift

@Youngminah Youngminah changed the title Type과 메모리 저장 공간 Value type vs Reference type : Memory Jan 10, 2022
@Youngminah Youngminah changed the title Value type vs Reference type : Memory Memory Value type vs Reference type Jan 12, 2022
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