[iOS] iOS의 운영체제, 스레드, 메모리 관리 (ARC, GCD 등)

Zerom·2024년 4월 9일
0

iOS 질문 답변

목록 보기
9/9
post-thumbnail

📚 질문

🧑‍💻 운영체제의 역할과 iOS에서의 운영체제 구조에 대해 설명해주세요.

  • 운영체제는 자원관리, 자원보호, 하드웨어 / 소프트웨어 인터페이스를 제공하며 효율성, 안정성, 확장성, 편리성을 목표로 동작합니다.
  • iOS에서의 운영체제는 하위 계층부터 Core OS / Core Service / Media / Cocoa Touch / Application으로 구성되어 있으며, 하위 계층일수록 하드웨어에 가깝고 기본이 되는 층이며, 상위로 갈수록 사용자와 관련있는 계층입니다.

🧑‍💻 프로세스와 스레드의 차이점, iOS에서의 프로세스와 스레드 관리 방법에 대해 설명해주세요.

  • 프로세스는 운영체제로부터 자원을 할당받는 작업의 단위이고 스레드는 프로세스가 할당받은 자원을 이용하는 실행의 단위입니다.
  • 즉, 프로세스는 실행파일이 메모리에 적재되어 CPU를 할당받아 실행되는 것이고, 스레드는 한 프로세스 내에서 실행되는 동작의 단위입니다.
  • 프로세스는 메모리 공간에 code, data, heap, stack 영역이 있는데, 스레드는 프로세스내에서 stack 영역을 제외한 code, data, heap 영역을 공유합니다.
  • iOS에는 Main과 Global Thread가 있으며 애플에서 제공하는 API인 GCD, NSOperation을 활용해 Multi Threading을 관리합니다.

🧑‍💻 메모리 관리 기법 중 iOS에서 사용되는 방식과 그 특징에 대해 설명해주세요.

  • iOS에서는 Objective-C를 사용할 때에는 MRC를 사용했으며, 현재 Swift에서는 ARC를 활용해 메모리를 관리합니다.
  • ARC는 Automatic Reference Counting의 줄임말로 메모리의 참조 횟수를 계산하여 참조 횟수가 0이 되면 메모리에서 해제하는 방식을 통해 메모리 관리를 하며 메모리 중 Heap 영역을 관리합니다.

📚 참고

🍎 운영 체제의 역할과 목표

  1. 자원 관리 : 여러 응용 프로그램이 자원을 요청하면 적절한 순서로 배분하고 회수하여 자원을 효율적으로 관리 => 효율성
  2. 자원 보호 : CPU, 메모리 등에 대한 사용자와 응용 프로그램의 직접 접근 제한 => 안정성
  3. 하드웨어 인터페이스 제공 : 다양한 제조사, 각기 다른 구성으로 되어 있는 마우스, 키보드 등을 복잡한 과정없이 사용할 수 있도록 하드웨어 인터페이스를 제공. 일부 하드웨어는 직접 드라이버(하드웨이 인터페이스)를 설치해야함 => 확장성
  4. 소프트웨어 인터페이스 제공 : 사용자가 운영체제를 편리하게 사용하기 위해 제공되는 것으로, 대부분의 작업을 마우스로 수행하거나 스마트폰의 터치스크린 등을 통해 제공되는 기능 => 편리성

🍎 iOS 운영체제 구조

  • iOS는 Unix 기반의 맥 OS X를 기반으로 다윈 커널을 가지고 있는 모바일 OS
  • 아래층부터 Core OS / Core Service / Media / Cocoa Touch / Application으로 이루어져 있으며 아래로 갈수록 가장 기본이 되는 층, 위로 갈수록 사용자와 관련이 있는 층
  • 하위 계층은 iOS의 핵심 부분 또는 하드웨어에 가까움

Application

  • iOS의 가장 바깥 계층으로, Apple App, Third-Party App이 여기 속함
  • 사용자와 가장 맞닿아 있는 계층

Cocoa Touch

  • 화면의 그래픽 UI 및 터치의 기능을 제공함
  • UIKit, MapKit, MessageUI등이 여기에 속함
  • 실제로 개발할 때 가장 많이 접하게 되는 계층

Media

  • 그래픽이나 오디오, 비디오 등 멀티미디어 기능을 제공하는 계층
  • C와 Objective-C가 혼합되어 있는 형태
  • AVFoundation(미디어 재생관련), MediaPlayer(플레이어), Core Image(이미지 가공)등의 기능이 있음

Core Service

  • GPS 나침반, 가속도 센서, 자이로스코프 디바이스 등 하드웨어적 기능들이 속함
  • Core Os에서 제공하지 않는 기능들을 포함
  • 내부 데이터 / 위치 / 센서 등의 기능을 제공
  • CoreMotion(기기 센서), Accounts(계정 관리), Core Foundation(데이터 관리)등의 기능을 제공

Core OS

  • 하드웨어와 가장 가까이 있는 최하위 계층
  • 시스템의 핵심 기능을 포함하는 기본적인 부분들을 관리

🍎 iOS Thread

iOS의 Main Thread

  • iOS에서 Main Thread는 오직 한개만 존재
  • Main Thread는 Interface Thread라고도 불리며, UI와 관련된 작업인 모두 Main Thread에서 동작해야됨
  • Main Thread는 MainQueue에서 실행되는데 Main Queue가 Serial Queue이기 때문에 한번에 한 개의 Task밖에 실행하지 못함
  • 따라서 UI를 실행하는 데에 영향을 줄만한 코드들은 Global Thread로 실행시켜야됨

iOS의 Global Thread

  • Background Thread라고도 불리며, iOS에서의 Framework들은 모두 Background에서 구동됨
  • 몸체는 Background에 있지만, 가끔 필요할 때 Main Thread에게 요청
  • 예를 들어, 음악 재생에 필요한 Framework 작업들은 모두 Background에서 실행되고, 필요에 따라 음악 재생이 성공했음을 알리기 위해 Delegate, Completion Handler 등을 통해 Main Thread에게 알려 통제할 수 있음
  • 자동으로 Background에서 실행되는 것 이외에도 코드 실행이 오래 걸리는 작업은 직접 Background Thread로 실행시켜야 함

NSOperation

  • Multi Threading을 위한 Objective-C 기반의 고수준 API
  • 내부적으로는 C로 구현된 GCD를 고수준 언어로 Wrapping한 것
  • GCD보다 다소 무겁고 약간의 오버헤드를 발생시킴
  • 다만 고수준 API인 만큼 GCD엔 없는 기능들을 사용할 수 있다는 장점이 있음
  • 작업 취소, KVO, 작업 재사용 등 GCD에서 하려면 다소 귀찮은 작업들을 제공하기 때문에 편하다는 장점이 있음
  • NSOperation의 동작 방식은 작업 단위인 NSOperation을 NSOperationQueue에 추가하여 실행시키는 방법
  • NSOperationQueue는 Concurrent Queue로 동작

GCD

  • Multi Threading을 위한 C언어 기반의 저수준 API
  • C언어 기반이기 때문에 NSOperation보다 가볍고 성능면에서 좋다는 장점이 있음
  • Block(Closure)로 구현되어 있어 코드 가독성면에서 좋고 간단하게 사용 가능
  • Dispatch Queue라는 것을 사용해서 Multi Threading을 지원
  • Dispatch Queue는 2가지 Type이 존재
    • Serial Queue : Task(작업)들을 순차적으로 처리하며, 한 번에 한 개의 Task 밖에 처리하지 못함
    • Concurrent Queue : 동시에 여러 개의 Task들을 처리
  • Dispatch Queue는 App이 실행됨과 동시에 구조적으로 2가지 Queue가 자동 생성
  • Main Queue (Serial Queue)
    • Main Thread에서 사용되며 UI 관련 작업은 이곳에서 처리되어야 함
    • MainQueue에는 절대 Sync Task를 추가할 수 없음 (Main Thread가 Thread-Safe하지 않아서, 컴파일 시 문제 없지만 런타임 에러로 발생)
DispatchQueue.main.async { // 원하는 작업 }
  • Global Queue (Concurrent Queue)
    • 편의상 사용할 수 있게 만들어 놓은 Concurrent Queue
    • Qos(Quality of Service) 지원 (우선 순위)
    • Qos를 잘 활용하면 에너지 효율성이 좋아진다고 함
    • qos를 지정하지 않으면 .Default로 지정됨
DispatchQueue.global().sync { // 원하는 작업 }
DispatchQueue.global().async { // 원하는 작업 }
DispatchQueue.global(qos: .userInteractive).sync { // 원하는 작업 }
명칭사용 용도동작 시간
userInteractive중요도가 높고 즉각적인 반응이 요구되는 작업일 때 사용
(UI업데이트, 이벤트 핸들링 등)
Main Thread에서 실행되는 Qos
즉각적으로 실행
userInitiated유저가 빠른 결과를 기대할 때 사용
저장된 파일을 열거나 할 때 사용
몇 초 이하나 거의 즉각적
default작업을 분리하지 않을 때 사용되는 Qos로 기본값
utility즉각적인 결과가 필요하지 않을 때
프로그레스 바가 등장하는 작업에 어울림
(네트워크, 다운로드, 계산, 데이터를 가져오기 등을 처리 등)
몇 초 ~ 몇 분
background급히 필요하지 않은 작업일 때
사용자에겐 보이지 않는 처리 (ex. 백업)
background로 줄 경우 iPhone 저전력 모드에선 실행되지 않는다
몇 분 ~ 몇 시간
unspecifiedQos 정보가 없음을 나타냄
시스템에게 Qos를 추론하라는 신호를 줌
  • Private Queue (사용자 지정 큐)
    • 위 방법 외에도 직접 Queue를 만들어 사용할 수 있음
let myQueue = DispatchQueue.init(label: "myQueue", qos: .background, attributes: .concurrent)
myQueue.async { // 원하는 작업 }

🍎 iOS 메모리 관리

GC VS RC

GCRC
참조 계산 시점Run Time
어플 실행 동안 주기적으로 참조를 추적하여 사용하지 않는 instance를 해제함
Complie Time
컴파일 시점에 언제 참조되고 해제되는지 결정되어 런타임 때 그대로 실행됨
장점RC에 비해 인스턴스가 해제될 확률이 높음개발자가 참조 해제 시점을 파악할 수 있음
RunTime 시점에 추가 리소스가 발생하지 않음
단점개발자가 참조 해제 시점을 파악할 수 없음
RunTime 시점에 계속 추적하는 추가 리소스가 필요하여 성능저하가 발생할 수 있음
순환 참조가 발생될 시 영구적으로 메모리가 해제되지 않을 수 있음

ARC (Automatic Reference Counting)

  • 메모리 영역 중 Heap 영역을 관리
  • 클래스 인스턴스가 더 이상 필요하지 않을 때 메모리를 자동으로 해제
  • 메모리의 참조 횟수(RC)를 계산하여, 참조 횟수가 0이 되면 더 이상 사용하지 않는 메모리라 생각해서 해제함
  • 그렇기 때문에 모든 인스턴스는 자신의 RC 값을 가지고 있음
  • 인스턴스의 주소값을 변수에 할당할 때 참조 횟수가 +1이 됨
    • 인스턴스를 새로 생성할 때
    • 기존 인스턴스를 다른 변수에 대입할 때
  • 다음과 같은 경우에 참조 횟수가 -1이 됨
    • 인스턴스를 가리키던 변수가 메모리에서 해제되었을 때
    • nil이 지정되었을 때
    • 변수에 다른 값을 대입했을 때
    • 프로퍼티의 경우, 속해 있는 클래스 인스턴스가 메모리에서 해제될 때

🔖 참고사이트
1. 질문 참고
2. 운영체제 참고
3. iOS 운영체제 참고
4. iOS Thread 참고
5. iOS ARC 참고

profile
꼼꼼한 iOS 개발자 /
Apple Developer Academy @ POSTECH 2기 / 멋쟁이사자처럼 앱스쿨 1기

0개의 댓글