Open longlivedrgn opened 7 months ago
운영체제는 한글로 들으면 조금 잘 와닿지 않는데 영어로는 Operation system입니다. 즉 실제로 하드웨어를 운영하는 시스템, 각 하드웨어를 동작시키고 연결짓는 소프트웨어입니다. 이를 통해 개발자 및 사용자들이 하드웨어를 잘 몰라도 앱을 개발하고 사용할 수 있도록 돕습니다. iOS는 위 맥락과 더불어 각 애플리케이션을 샌드박스라는 형태로 구성시킵니다. 이를 통해 특정 하드웨어와 유저 프라이버시와 연관된 데이터 접근을 반드시 운영체제를 거쳐 사용자가 허락을 했을 때만 이용할 수 있도록 만들고 있습니다.
1-a) 샌드박스가 뭔가요?
아파트 같은데 놀이터가 있으면, 해당 놀이터는 쉽게 보호받을 수 있게 됩니다. 아파트 경비원을 포함해서 주위 어른들이 아이들을 보살펴줄테니까요. 이러한 놀이터를 샌드박스라고 하는데, 시스템개발에서는 이러한 맥락을 차용하여 운영체제가 경비원의 일을 하여 위험요소로부터 사용자를 보호해주는 역할을 합니다. 사용하고자 하는 애플리케이션 자체가 위험요소일 수 있기 때문에 위에서 이야기를 드린 것처럼 특정 권한에 대해 유저가 확인을 하도록 거치기도 하는 것이고, 외부 애플리케이션이 침입하거나 하는 것을 막는 일도 합니다.
프로세스는 실제로 메모리에 올라가 실행중인 프로그램, 애플리케이션을 의미합니다. 저희가 보통 개발을 하면서 이야기하는 스레드는, 이러한 프로세스의 구성요소로 실제로 소스코드를 동작시키는 논리적 맥락인데요. 이 말이 조금 어렵게 느껴진다면 개발자가 명령을 하면, 그 명령을 수행하는 주체라고 표현해도 괜찮을 것 같습니다. 나아가 이러한 스레드는 CPU의 구성요소인 스레드와 연결되는데, 하드웨어와 관련된 부분이기 때문에, 앞서 운영체제에서 이야기를 드렸던 것처럼 결국은 운영체제가 관리를 하게 됩니다. 즉 개발자는 운영체제를 통해 하드웨어 스레드의 동작 원리나 제약을 잘 모르더라도 소프트웨어적인 스레드를 통해, 쉽게 이를 사용할 수 있게 됩니다. iOS의 프로세스 관리방법은 UIApplicationDelegate의 구성요소를 보면 쉽게 파악할 수 있는데요. 외우진 않아서 구성요소를 모두 정확히 기억하지는 않지만, foreground, background, active, suspended 등이 있는 것으로 기억합니다. 특히 NotificationCenter.default를 통해 관련 노티피케이션을 전파해서 개발자가 쉽게 활용할 수 있도록 돕고 있습니다. iOS의 스레드 관리방법은 질문의 의도를 사실 잘 모르겠는데요. 운영체제의 스레드 관리방법은 제가 운영체제 개발자가 아니라 잘 모릅니다. 일반적으로는 스레드풀이라고하는 기술을 이용하여 구현하는 것으로 알고 있는데, iOS도 그런지는 잘 모르겠습니다. 또 제가 잘 모르는 걸 보면, 운영체제를 잘 개발한 것 같습니다. 개발을 하면서 스레드를 어떻게 관리하는지 물어보는 질문이라면, NSThread를 통해 직접 생성하고 관리할 수는 있습니다. 생명주기는 ARC에 의해 관리되고, 나아가 각 스레드가 무슨 일을 하는지 관리하는 맥락이라면 또 각 스레드가 어떤 일을 할지를 결정하고 개발할 수도 있습니다. 예를 들면 2번 쓰레드는 네트워킹용, 3번 쓰레드는 데이터 처리용 등... 시스템에서 강제하는 부분도 있는데 메인스레드는 특히 UI를 갱신하는 용도로 이용됩니다. 다만 이런 관리방법은 개발자가 그만큼 정의해야할 게 많아지므로, 메인스레드를 제외하고는 요즈음에는 이런 식으로 이용하지는 않고, GCD, OperationQueue, Combine, Swift Concurrency과 같은 기술을 이용하여 스레드에 대한 관리는 최소한으로 하는 편입니다.
2-a) 왜 위 기술을 이용하면 스레드에 대한 관리를 최소한으로 할 수 있나요?
부연설명을 하면 먼저 메인스레드에서 모든 일을 하게 되면 애초에 스레드를 몰라도 됩니다. 스레드를 명시하지 않으면, 묵시적으로 거의 모든 코드는 메인 스레드에서 동작하기 때문입니다. 메인스레드에서 모든 일을 하지 않는다는 것은, 위 이야기의 연장선에서 일을 하는 주체가 여러개가 된다는 것입니다. 당연히 더 빨리 많은 일을 할 수 있게 되지만, 현실세계와 똑같이 사공이 많으면 배가 산으로 갑니다. 컴퓨터의 세계에서는 데이터가 손실되거나, 앱이 멈추거나 강제로 종료되는 일이 되는데요. 이 때문에 스레드를 이용하면 이용할수록 스레드에 대한 관리가 필요해지게 됩니다. 여기서부터는 제 주관인데요. 위 기술들 중 GCD, OperationQueue, Combine은 '사공이 많으면 배가 산으로 간다'는 문제를 극복하고자 나온 기술을 아닌 것 같습니다. 다만 어떻게 코드를 풀어나갈 것인가, 더 빨리 더 많은 일을 시키는 방법을 어떻게 구조화할 것인가에 관점으로 나온 기술로 보입니다. 어쨌거나 이를 통해 스레드를, 일을 하는 주체를 추상화하여, 실제로 여러명에게 일을 시키는 게 아니지만 여러명에게 일을 시키는 것처럼 만들어줘서, 상대적으로 관리 자체는 편해지는 편입니다. Combine은 제가 보기에 또 결이 다르기는 한데 이러한 맥락은 공유합니다. Swift concurrency는 위 기술들의 연장선에서 '사공이 많으면 배가 산으로 간다'는 관점에서 나온 기술로 보입니다. 그래서 이러한 사공들을 만들고 동기화하는 손쉬운 방법을 개발자에게 지원해주는데, 결과적으로 스레드에 대한 관리를 최소화하며, 매우 쉽게 여러명에게 일을 시켜 더 빨리 많은 일을 할 수 있도록 좋습니다.
iOS는 Automatic Reference Counting(이하 ARC)을 이용하는데요. 가장 큰 특징은 사용이 끝난 인스턴스는 메모리에서 바로 내리는 것입니다. 그리고 사용이 끝났다는 것을 체크하기 위해서 컴파일 타임에 두 가지 작업이 들어갑니다. 하나는 참조타입에 레퍼런스 카운트라는 프로퍼티를 삽입하는 것이고, 다른 하나는 인스턴스 사용 전후에 레퍼런스 카운트를 올리고 내리는 코드를 삽입하는 것입니다. 이 때 개발자는 해당 인스턴스의 성격과 함께 레퍼런스 카운팅을 고려하여 weak
, unowned
와 같은 키워드를 사용해 인스턴스가 매끄럽게 해제되게 만들거나, 오히려 반대로 strong
키워드를 통해 조금 더 길게 메모리에 유지되게 하는 것을 고려할 필요가 있습니다.
3-a) 더 길게 메모리에 유지되어야하는 케이스에는 어떤 게 있나요?
사실 흔치 않은 일이기에 약간의 상상력과 가정이 필요한 일인데요. 예를 들면 유저가 광고를 하나 봐야하고, 해당 광고를 다 본다는 기준이 서버에 15초를 봤다고 전송하는 것이라고 가정해보겠습니다. 그리고 사전에 모든 광고는 15초는 넘도록 정책을 정했지만, 운영 중 부득이하게 15초보다 짧은 광고들도 나오게 된 것입니다. 이를 해결하는 방법은 여러가지일 것입니다. 비용 측면에서 직관적으로 생각하면, 광고가 정책보다 짧은 경우에는 시간을 딜레이 시키는 것보다는 광고가 종료됐을 때 15초는 봤다고 서버에 전송하는 게 최선일 것 같습니다. 하지만 일단 쉬운 방법은, 해당 광고를 메모리에 일부러 더 유지시켜서 15초가 지났을 때 해제시키며 서버에 전송하는 것도 방법이 될 수 있을 것 같습니다. 앞서 말씀드린 것처럼 흔치 않은 일이라 약간 억지스러운 면이 있으나, 실제 기능구현을 할 때에도 동기화와 관련된 측면에서 한번쯤은 고려해볼 요소가 될 수 있을 것 같습니다.
샌드박스에 대한 이야기는 1)과 1-a)에서 이야기를 했는데요. 앱 간 데이터 공유 방법은 질문의 의도를 잘 모르겠네요. 생각나는 걸 일단 적어보자면, 첫번째로 서버도 앱이라는 점에서 통신 프로토콜을 통해 앱 간 데이터를 공유할 수도 있고요. 두번째로 해당 서버를 통해 서로 다른 두 클라이언트가 데이터를 공유할 수도 있고요. 예를 들면 네이버 블로그 같은 것처럼 네이버 서버가 있고, 수많은 사용자들이 해당 블로그를 공유하는 것처럼요. iOS 앱 내에서 서버를 두지 않고 데이터를 공유하는 건 구체적으로는 사실 잘 모르겠는데요. 제 경험에 비추어 볼 때 Share extension을 통해 구현하거나, 클립보드를 이용하거나, URL을 통해 다른 앱을 런치시키며 데이터를 넘겨주거나 하는 방법이 있을 것 같습니다.
코어 OS
/ 코어 서비스
/ 미디어
/ 코코아 터치
계층으로 이루어져 있습니다. -> 요거는 꼬리질문 나오면 대답 못하겠네여ㅋㅋㅋ 더 알아보겠습니다..: 실행할 프로그램에 필요한 자원을 할당하는 프로그램이다.
자바의 메모리 관리 기법인 Garbage Collection과 비교해보도록 하겠다.
ARC | GC | |
---|---|---|
동작 | 컴파일 타임에 객체의 참조 횟수 추적 | 런타임의 백그라운드에서 동작 |
메모리 해제 시점 | reference count가 0일때, 실시간으로 메모리 해제 | 불확실한 간격으로 작동되기 때문에 객체가 더 이상 사용되지 않는 시점에 정확히 해제되는 것이 아님. |
: 외부로부터 들어온 프로그램이 보호된 영역에서 동작해 시스템이 부정하게 조작되는 것을 막는 보안 형태이다. 쉽게 말하자면, 보호된 영역 안에서 프로그램을 작동시키는 보안 모델이다.
운영체제는 Operating SystemOS으로 불리며, 실행할 프로그램을 메모리에 적재(겹치지 않도록 적당한 공간 할당)하고.
더 이상 실행되지 않는 프로그램을 메모리에서 삭제하며 지속적으로 메모리 자원을 관리하는 시스템 소프트웨어이다.
운영체제는 응용 프로그램이 최대한 공정하게 CPU 자원을 사용하도록 할당한다. 이 외에도 시스템 자원을 관리한다. 프로그램이 올바르고 안전하게 실행되게 하는 기능
이 운영체제의 핵심 서비스에 속한다. 이러한 운영체제의 핵심 서비스를 담당하는 부분을 커널(kernel)
이라고 한다.
멀티태스킹을 지원하는 경우, 운영체제는 모든 프로세스들을 스케줄링하여 동시에 수행되는 것처럼 보이는 효과를 낸다.
iOS는 iPhone 및 iPad 장치용으로 설계한 운영체제로 Darwin을 기반으로 한다.
Apple Darwin 운영체제는 오픈소스로 배포되어 있다.
프로그램은 실행되기 전까지는 그저 보조기억 장치에 있는 데이터 덩어리일 뿐이지만, 보조기억 장치에 저장된 프로그램을메모리에 적재하고 실행하는 순간 그 프로그램은 Process
가 된다. Thread는 프로세스를 구성하는 흐름의 단위
이다.
프로세스는 운영체제로부터 시스템 자원을 할당받는 작업의 단위이다.
프로세스는 CPU 시간, 운영되기 위해 필요한 주소 공간 그리고
Code, Data, Stack, Heap의 구조로 되어있는 메모리 영역을 시스템 자원으로 할당 받는다
. 프로세스는 각각 독립된 메모리 영역을 할당받는다.
기본적으로 프로세스당 최소 1개의 메인 스레드를 갖는다.
스레드는
프로세스의 특정한 수행 경로로 프로세스 내에서 각각 Stack만 따로 할당받고 Code, Data, Heap 영역은 공유
한다.
iOS에서 프로세스를 관리하는 것은 foreground와 background에서 사용되는 것으로 구분이 되어 관리가 된다. 필요에 따라 background가 중지되거나 종료될 수 있다. 멀티태스킹이 도입되면서 여러 앱을 사용할 수 있게 되었다.
iOS에서 스레드를 GCDGrand Central Dispatch, Operation, NSThread, pthread로 관리할 수 있었으며, 현재에는 Swift Concurrency를 통해 데이터 레이스, 데드락 방지 및 다양한 동시성 문제를 해결할 수 있다.
Multithreading에서는 Stack을 제외한 메모리 영역을 공유하는 반면 Multiprocessing에서는 context switching이 발생하면서 오버헤드가 발생하게 된다. 그렇지만 Multithreading에서는 하나의 스레드에서 문제가 생기면 다른 스레드도 문제가 생기고, 디버깅도 어려운만큼 설계가 중요하다. 하지만 컴퓨터 시스템 자원을 적게 소모하는 장점이 있다.
Objective-C에서는 수동으로 메모리를 C언어와 같이 직접 관리를 했다면, Swift에서는 ARC를 사용하여 앱의 메모리 사용량을 추적하고 관리한다. 메모리 관리가 Swift에서 작동을 의미하며, 직접 생각할 필요가 없다. 해당 인스턴스가 더 이상 필요하지 않을 때 인스턴스에서 사용하는 메모리를 자동으로 해제한다.
ARC는 현재 각 클래스 인스턴스를 참조하는 properties, constants 그리고 variables의 수를 추적한다. 활성 참조가 하나 이상 존재하는 한 인스턴스 할당을 해제하지 않는다. 해당 인스턴스를 확고하게 유지하고 참조가 남아있는 경우 할당 해제할 수 없기 때문에 strong refence라고 한다.
Core OS Layer에는 앱 보안과 관련된 기능을 구현한다. 그 중에서도 Sandbox는 악성 코드가 앱을 악용하는 경우 도난, 손상 또는 삭제된 사용자 데이터에 대한 최후의 방어선을 제공한다. 또한, 코딩 오류로 인한 피해를 최소화한다.
그 전략으로 두 가지가 존재한다.
Network, Hardware, App data, User Files를 사용하려면 의도를 명시해야 한다. 명시적으로 요청되지 않은 리소스에 대한 접근(권한을 초과하는 부분)은 런타임 시 시스템에 의해 거절된다.
참고) 프로세스 vs 프로세서 vs 프로시저 (정리 중ㅠ)
프로세스가 프로세서를 할당받기 위해 기다리고 있는 상태를 '준비'라고 한다.
프로세스는 프로세서가 할당되는 실체로서, 디스패치가 가능한 단위이다.
프로세스는 프로시저가 활동 중인 것이며, 비동기적 행위를 일으키는 주체다.
프로세스는 운영체제가 관리하는 실행 단위라고 할 수 있다.
프로세스는 프로시저가 활동 중인 것 (정리 중ㅠ)
- 위 문장에서 '프로시저'는 '스레드'일까?
iOS에서의 프로세스와 스레드 관리 방법
↘︎ iOS는 AP가 필요로 하는 캐싱 작업을 수행(적절한 메모리 공간을 할당하고 관리) ↘︎
4/16 23:59