본문 바로가기

iOS

가비지 컬렉터(Garbage Collector)

728x90
반응형
SMALL

가비지 컬렉션(Garbage Collection) 

iOS 운영체제의 메모리 관리는 가비지 컬렉션(Garbage Collection) 기술을 사용합니다. 가비지 컬렉터는 자동으로 더 이상 사용하지 않는 객체를 메모리에서 해제하여 앱의 성능을 최적화합니다.

iOS 가비지 컬렉터는 애플이 직접 개발한 Objective-C나 Swift와 같은 프로그래밍 언어에서 사용할 수 있습니다. iOS 앱 개발을 위해 사용되는 Xcode IDE는 애플이 개발한 Clang 컴파일러를 기반으로 하며, 이 컴파일러는 Objective-C와 Swift 코드에서 가비지 컬렉션을 지원합니다.

가비지 컬렉터는 자동으로 메모리 관리를 수행하므로 개발자는 수동으로 메모리를 관리할 필요가 없습니다. 그러나, 이 기능을 사용하더라도 여전히 메모리 누수나 성능 문제가 발생할 수 있으므로 개발자는 코드를 최적화하고 메모리 사용을 최대한 줄이는 데 노력해야 합니다.

 

**Clang** (https://clang.llvm.org/)

Clang은 LLVM(코드 최적화 및 변환을 위한 오픈 소스 컴파일러 프레임워크)의 C, C++, Objective-C 및 Objective-C++ 컴파일러입니다. Clang은 LLVM의 일부로 개발되었으며, GCC(GNU Compiler Collection)와 비교하여 더 빠르고 효율적인 컴파일을 제공합니다.

Clang은 다양한 기능과 장점을 가지고 있습니다. 먼저, Clang은 C++11, C++14, C++17 및 C++20의 최신 표준을 지원하므로, 개발자는 최신 언어 기능을 활용할 수 있습니다. 또한, Clang은 강력한 경고 및 오류 메시지를 제공하여 개발자가 코드를 디버그하고 수정하는 데 도움을 줍니다.

또한, Clang은 코드 최적화를 위한 강력한 기능을 제공합니다. Clang은 LLVM을 기반으로 하므로, LLVM의 강력한 코드 최적화 기능을 활용할 수 있습니다. 이러한 최적화 기능은 실행 시간 및 메모리 사용량을 최적화하여 프로그램의 성능을 향상시킵니다.

Clang은 또한 컴파일 시간을 단축시키는 기능도 제공합니다. Clang은 강력한 인터페이스를 제공하여 병렬 컴파일, 캐시 기반 빌드 및 자동 의존성 추적과 같은 기능을 활용할 수 있습니다.

마지막으로, Clang은 오픈 소스 라이선스를 사용하여 무료로 사용할 수 있습니다. 이는 개발자가 더 많은 리소스를 코드 작성 및 최적화에 투자할 수 있도록 도와줍니다.

 

 

가비지 컬렉터가 제거하지 못하는 경우는 크게 두 가지로 나뉩니다.

  • 첫 번째는 객체 간의 순환 참조(circular reference)가 발생하는 경우입니다. 예를 들어, 객체 A가 객체 B를 참조하고, 객체 B가 객체 A를 참조하는 경우입니다. 이 경우, 두 객체 모두 참조되고 있기 때문에 둘 다 제거되지 않아 메모리 누수가 발생할 수 있습니다.
  • 두 번째는 앱 내부에서 C 언어 기반의 코드나 Objective-C의 __bridge_transfer 또는 CFRelease()와 같은 메모리 해제 함수를 사용하는 경우입니다. 이 경우 가비지 컬렉터는 해당 객체를 해제하지 않으므로 메모리 누수가 발생할 수 있습니다.

이러한 상황을 방지하기 위해서는 순환 참조를 피하고, 메모리 해제 함수를 사용할 때는 가비지 컬렉터와 함께 사용해야 합니다. 또한, 인스턴스 변수를 weak 또는 unowned로 선언하여 순환 참조를 방지하는 방법도 있습니다. 이렇게 함으로써 iOS 가비지 컬렉터를 보다 효율적으로 사용할 수 있습니다.

 

*__bridge_transfer

__bridge_transfer는 Objective-C 객체를 Swift 객체로 변환할 때 사용되는 키워드 중 하나입니다. 이 키워드는 Objective-C 객체를 참조하는 CFTypeRef 또는 CGTypeRef 등의 Core Foundation 객체를 Swift 객체로 변환할 때 사용됩니다.

bridge_transfer는 Objective-C 객체의 메모리 관리를 Swift 객체에게 전달하여, Swift 객체가 Objective-C 객체를 참조하는 동안 메모리 누수를 방지합니다. 이를 통해 개발자는 수동으로 Objective-C 객체를 해제하지 않고도 메모리 관리를 처리할 수 있습니다.

예를 들어, 다음과 같은 Objective-C 메서드가 있다고 가정해 봅시다.

//Foundation 프레임워크에서 제공하는 클래스 및 함수를 사용하기 위한 헤더 파일입니다
#import <Foundation/Foundation.h>

//C 언어의 main() 함수입니다. @autoreleasepool 블록은 Objective-C의 자동 메모리 관리 기능을 사용하기 위한 코드 블록입니다.
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
//CFStringCreateWithCString 함수를 사용하여 "Hello, World!" 문자열을 포함하는 Core Foundation 문자열 객체 cfString을 생성합니다. kCFAllocatorDefault 매개변수를 사용하여 문자열 객체에 대한 메모리를 할당합니다. kCFStringEncodingUTF8 매개변수를 사용하여 문자열이 UTF-8 인코딩되도록 지정합니다.
        CFStringRef cfString = CFStringCreateWithCString(kCFAllocatorDefault, "Hello, World!", kCFStringEncodingUTF8);
        
//__bridge_transfer 키워드를 사용하여 Core Foundation 문자열 객체 cfString의 소유권을 Objective-C 문자열 객체인 nsString으로 전달합니다. 이를 통해 ARC에서는 이후 cfString의 참조를 자동으로 해제할 수 있습니다. NSString 클래스로 캐스팅하여 cfString을 Objective-C 객체로 변환합니다.
        NSString *nsString = (__bridge_transfer NSString *)cfString;
        
//NSLog() 함수를 사용하여 Objective-C 문자열 객체 nsString을 출력합니다. %@ 포맷 문자열을 사용하여 문자열 객체의 값을 출력합니다. 이를 통해 "Hello, World!" 문자열이 출력됩니다.

        NSLog(@"%@", nsString);
    }
//C 언어에서 main() 함수가 끝나면 정수형 값을 반환해야 합니다. 보통 0을 반환하여 프로그램이 정상적으로 종료되었음을 나타냅니다.
    return 0;
}

 

 

*CFStringCreate()

CFRelease()는 macOS 및 iOS의 Core Foundation 프레임워크에서 참조된 Core Foundation 객체를 해제하는 함수입니다. CFStringCreate()와 같은 함수를 사용하여 Core Foundation 객체를 생성하면 해당 객체에 대한 참조가 생성되고, CFRelease() 함수를 사용하여 해당 참조를 해제할 수 있습니다.

//Foundation 프레임워크에서 제공하는 클래스 및 함수를 사용하기 위한 헤더 파일입니다
#import <Foundation/Foundation.h>

//C 언어의 main() 함수입니다. @autoreleasepool 블록은 Objective-C의 자동 메모리 관리 기능을 사용하기 위한 코드 블록입니다.
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
//Core Foundation 문자열 객체인 CFStringRef을 생성하는 함수입니다. 이 함수는 C 문자열을 UTF-8 인코딩으로 변환하여 Core Foundation 문자열 객체를 생성합니다. 이 문자열 객체는 myString이라는 포인터 변수에 저장됩니다.
        CFStringRef myString = CFStringCreateWithCString(NULL, "Hello, World!", kCFStringEncodingUTF8);
        
//Core Foundation 객체의 값을 출력하는 함수인 CFShow() 함수를 사용하여, 이전에 생성한 문자열 객체의 내용을 콘솔에 출력합니다.
        CFShow(myString);
        
//Core Foundation 객체에 대한 참조를 해제하는 함수입니다. 메모리 누수를 방지하기 위해, Core Foundation 객체를 사용한 후에는 해당 객체에 대한 참조를 해제해야 합니다.
        CFRelease(myString);
    }
//C 언어에서 main() 함수가 끝나면 정수형 값을 반환해야 합니다. 보통 0을 반환하여 프로그램이 정상적으로 종료되었음을 나타냅니다.
    return 0;
}

 

다음은 CFStringCreate() 함수를 사용하여 Core Foundation 문자열 객체를 생성하고, 이를 해제하기 위해 CFRelease() 함수를 사용하는 예제 코드입니다.

 

이 코드에서 CFSTR() 함수는 C 문자열을 Core Foundation 문자열 객체로 변환합니다. CFShow() 함수는 Core Foundation 객체를

출력하는 데 사용됩니다. 마지막으로, CFRelease() 함수는 해당 참조를 해제하여 메모리 누수를 방지합니다.

 

iOS에서 가비지 컬렉션(Garbage Collection)과 ARC(Automatic Reference Counting)는 모두 메모리 관리를 자동화하는 방식입니다. 그러나 두 가지 방식은 각각 장단점이 있습니다.

가비지 컬렉션의 장점

- 개발자가 메모리 관리에 대한 부담을 덜어준다는 것입니다.

가비지 컬렉션을 사용하면 개발자는 메모리 해제를 명시적으로 할 필요가 없으며, 메모리 누수와 같은 문제도 최소화됩니다. 또한, 가비지 컬렉션을 사용하면 코드 작성 시간을 단축시킬 수 있습니다.

가비지 컬렉션의 단점

- 실행 시간이나 메모리 사용량 등이 예측할 수 없다는 것입니다.

가비지 컬렉션은 런타임 시에 메모리 해제를 수행하므로, 예기치 않은 시간에 가비지 컬렉션이 발생할 수 있습니다. 또한, 가비지 컬렉션을 사용하면 런타임 오버헤드가 발생하며, 이는 프로그램 성능에 영향을 줄 수 있습니다.

 

ARC의 장점

- 가비지 컬렉션과 비교하여 실행 시간 및 메모리 사용량 등이 예측 가능하다는 것입니다.

ARC는 컴파일 시간에 자동으로 메모리 해제 코드를 삽입하므로, 런타임 오버헤드가 발생하지 않습니다. 또한, ARC는 메모리 누수와 같은 문제를 사전에 방지할 수 있으며, 가독성이 좋은 코드를 작성할 수 있습니다.

ARC의 단점

- 개발자가 메모리 관리에 대한 이해도가 필요하다는 것입니다.

ARC를 사용하더라도 개발자는 여전히 메모리 관리에 대한 이해도를 갖고 있어야 하며, Strong/Weak/Unowned와 같은 참조 타입을 적절하게 사용하여 메모리 관리를 해야 합니다. 또한, ARC를 사용하면 코드 작성 시간이 늘어날 수 있습니다.

728x90
반응형
LIST

'iOS' 카테고리의 다른 글

ARC(Automatic Reference Counting)  (0) 2023.04.11
NSLog, CFShow의 차이  (0) 2023.04.11
KVO - key-value-observing  (0) 2023.03.08
Html to AttributedString  (0) 2023.02.20
pageVC 안에 VC 안에 pageVC 안에 scrollView가 스크롤 되지않음  (0) 2022.11.30