Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

2장. 이 앱은 어떻게 실행되는가

“운영체제, 프로세스, 메모리”


이번 장에서 알게 될 것

  • 앱을 많이 켜면 왜 폰이 느려지는지
  • CPU가 동시에 여러 일을 하는 것처럼 보이는 비밀
  • “앱 강제종료“가 실제로 하는 일
  • 2038년에 전 세계 컴퓨터에 닥칠 수 있는 문제

치킨 주문 여정: 앱이 켜진다

화면을 터치했습니다. 전기 신호가 발생했습니다. 그런데 이 신호를 받아서 “배달앱을 열어라“고 판단하는 건 누구일까요? 스마트폰 안에는 보이지 않는 관리자가 있습니다.


앱을 많이 켜면 왜 느려질까?

카카오톡, 유튜브, 배달앱, 브라우저, 음악 앱. 스마트폰에서 앱을 잔뜩 열어두면 점점 느려집니다. 그러다 앱 하나를 다시 열면 처음부터 새로 로딩되기도 합니다. 분명 끄지 않았는데 말입니다.

왜 그럴까요? 이걸 이해하려면, 스마트폰 안에서 벌어지는 두 가지를 알아야 합니다. CPU가 어떻게 일하는지, 그리고 메모리가 어떻게 쓰이는지.


CPU는 한 번에 하나만 한다

스마트폰에서 음악을 틀어놓고, 카카오톡으로 대화하면서, 배달앱을 검색합니다. 세 가지가 동시에 돌아가는 것처럼 보입니다.

사실은 아닙니다.

CPU는 한 순간에 하나의 작업만 처리할 수 있습니다. 그런데 엄청나게 빠르게 작업을 바꿔가면서 처리합니다. 음악 앱에 0.001초, 카카오톡에 0.001초, 배달앱에 0.001초. 이걸 너무 빠르게 반복하니까 우리 눈에는 세 개가 동시에 돌아가는 것처럼 보이는 겁니다.

이 작업 전환을 컨텍스트 스위칭(Context Switching) 이라고 합니다.

[그림 2-1] CPU 컨텍스트 스위칭

시간 →
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│음악 │카톡 │배달 │음악 │카톡 │배달 │음악 │카톡 │ ...
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
  ↑
  각 칸 = 수 밀리초 (0.00n초)
  사람 눈에는 "전부 동시에 돌아가는 것"으로 보임

요즘 스마트폰 CPU는 코어가 여러 개입니다. “옥타코어“라는 건 코어가 8개라는 뜻이고, 이 경우 진짜로 8개의 작업을 동시에 처리할 수 있습니다. 하지만 실행 중인 앱과 백그라운드 프로세스를 합치면 수십에서 수백 개에 달하기 때문에, 여전히 컨텍스트 스위칭은 끊임없이 일어납니다.

그런데 이 8개의 코어가 전부 같지는 않습니다. 대부분의 스마트폰은 고성능 코어저전력 코어를 섞어서 씁니다. 게임처럼 무거운 작업은 고성능 코어가, 알림 확인이나 시계 표시 같은 가벼운 작업은 저전력 코어가 처리합니다.

왜 이렇게 나눌까요? 전부 고성능 코어로 채우면 배터리가 순식간에 닳기 때문입니다. 실제로 스마트폰이 하는 일의 대부분은 가벼운 작업입니다. 메시지 수신 대기, 화면 갱신, 백그라운드 동기화. 이런 일에 고성능 코어를 깨우는 건, 편의점에 우유 하나 사러 가는데 대형 트럭을 모는 것과 같습니다.

옥타코어 CPU 구조 (예시)

┌─────────────────────────────────────────┐
│  고성능 코어 (2개)   저전력 코어 (6개)    │
│  ┌────┐ ┌────┐    ┌──┐┌──┐┌──┐┌──┐┌──┐┌──┐ │
│  │ 🔥 │ │ 🔥 │    │💤││💤││💤││💤││💤││💤│ │
│  └────┘ └────┘    └──┘└──┘└──┘└──┘└──┘└──┘ │
│  게임, 카메라      알림, 동기화, 대기      │
│  → 빠르지만 전력↑   → 느리지만 전력↓       │
└─────────────────────────────────────────┘

RAM은 책상이다

CPU가 일하는 속도를 이해했으니, 이번에는 공간 이야기입니다.

비유를 하나 들어보겠습니다. 여러분이 공부를 한다고 합시다.

  • 책상 위에는 지금 보고 있는 교재, 노트, 필기구가 올라와 있습니다. 손만 뻗으면 바로 씁니다.
  • 서랍장 에는 나머지 책들이 들어 있습니다. 필요하면 꺼내와야 합니다. 시간이 좀 걸립니다.

스마트폰에서 RAM이 책상이고, 저장장치(SSD/Flash) 가 서랍장입니다.

[그림 2-2] RAM과 저장장치의 구조

┌──────────────────────────────────────────┐
│                 책상 (RAM)                │
│                                          │
│  ┌──────┐  ┌──────┐  ┌──────┐            │
│  │ 배달앱 │  │ 카톡  │  │ 음악앱│            │
│  │(실행중)│  │(대기) │  │(재생) │            │
│  └──────┘  └──────┘  └──────┘            │
│                                          │
│  ← 공간이 부족하면 하나를 치워야 함 →       │
└──────────────────────────────────────────┘
                    ↕ 꺼내기 / 넣기
┌──────────────────────────────────────────┐
│              서랍장 (저장장치)              │
│                                          │
│  사진, 동영상, 설치된 앱 수백 개...         │
│  용량은 크지만, 꺼내는 데 시간이 걸림       │
└──────────────────────────────────────────┘

앱을 여는 것은 서랍에서 교재를 꺼내 책상 위에 올리는 것과 같습니다. 앱이 RAM에 올라와야 CPU가 처리할 수 있습니다.

문제는 책상 크기에 한계가 있다는 겁니다. RAM이 8GB인 폰에서 앱을 20개 열면, 책상이 꽉 찹니다. 그러면 운영체제는 가장 오래 안 쓴 앱을 책상에서 치웁니다 — 서랍에 다시 넣는 겁니다. 나중에 그 앱을 다시 열면 서랍에서 꺼내와야 하니까, 처음부터 새로 로딩되는 것입니다.

“앱을 많이 켜면 느려진다“의 정체가 이겁니다. CPU가 느려지는 게 아니라, RAM이 부족해서 앱을 내렸다 올렸다 반복하느라 느려지는 것입니다.


운영체제: 보이지 않는 총 관리자

그렇다면 어떤 앱을 RAM에 올리고, 어떤 앱을 내릴지 결정하는 건 누구일까요? CPU 시간을 어떤 앱에 얼마나 배분할지 정하는 건?

운영체제(Operating System, OS) 입니다.

안드로이드, iOS, 윈도우, 맥OS — 이것들이 전부 운영체제입니다. 운영체제가 하는 일을 한마디로 요약하면 이렇습니다.

하드웨어와 앱 사이의 통역

앱은 하드웨어를 직접 제어하지 않습니다. “화면에 빨간 버튼을 그려라”, “스피커에서 소리를 내라”, “인터넷에 데이터를 보내라” — 이런 요청을 운영체제에게 합니다. 운영체제가 대신 하드웨어에 명령을 내립니다.

이렇게 하는 이유는 안전 때문입니다. 앱 하나가 하드웨어를 마음대로 조작할 수 있으면, 다른 앱의 데이터를 읽거나, 시스템 전체를 망가뜨릴 수 있습니다. 운영체제는 각 앱에게 허용된 범위만 쓰게 합니다. “카메라 접근을 허용하시겠습니까?” 같은 팝업이 뜨는 것도 이 때문입니다.

전원 버튼을 누르면 무슨 일이 벌어질까

운영체제가 모든 것을 관리한다면, 운영체제 자체는 누가 실행시킬까요?

전원 버튼을 누르면 가장 먼저 실행되는 것은 운영체제가 아닙니다. 칩에 내장된 아주 작은 프로그램 — 부트로더(Bootloader) — 가 먼저 깨어납니다. 부트로더는 하드웨어가 정상인지 간단히 확인한 뒤, 저장장치에서 운영체제를 찾아 RAM에 올립니다. 그제서야 운영체제가 주도권을 잡고 나머지를 실행합니다.

이 과정이 부팅(Booting) 입니다. 컴퓨터를 켤 때마다 로고가 뜨면서 잠시 기다리는 시간 — 그게 운영체제가 저장장치에서 RAM으로 올라오는 시간입니다. SSD가 빠른 컴퓨터에서 부팅이 빠른 이유도, 서랍(저장장치)에서 책상(RAM)으로 꺼내오는 속도가 빠르기 때문입니다.

프로세스: 실행 중인 앱의 진짜 이름

앱 아이콘을 누르면 “프로그램“이 실행됩니다. 이 실행 중인 프로그램을 프로세스(Process) 라고 합니다.

프로그램과 프로세스의 차이는 이렇습니다. 프로그램은 저장장치에 저장된 파일입니다 — 서랍 속의 교재입니다. 프로세스는 그 프로그램이 RAM에 올라와 실행되고 있는 상태입니다 — 책상 위에 펼쳐진 교재입니다. 같은 프로그램을 두 번 실행하면 프로세스가 2개 생깁니다.

“앱 강제종료“가 하는 일이 바로 이 프로세스를 죽이는(kill) 것입니다. RAM에서 해당 앱의 흔적을 완전히 지워버립니다. 책상 위의 교재를 덮어서 서랍에 집어넣는 게 아니라, 아예 책상 밖으로 치워버리는 겁니다.


가비지 컬렉션: 메모리 청소부

앱이 실행되면서 RAM에는 온갖 데이터가 쌓입니다. 이미지, 텍스트, 변수, 임시 계산 결과. 그런데 이 중 일부는 더 이상 필요 없어집니다. 이전 화면의 데이터, 이미 처리된 네트워크 응답 같은 것들입니다.

이 쓸모없어진 데이터를 자동으로 찾아서 치워주는 것이 가비지 컬렉션(Garbage Collection) 입니다. 말 그대로 쓰레기 수거입니다.

책상 위에 쓰다 만 메모지, 다 마신 커피잔이 쌓이면 공간이 부족해지는 것처럼, RAM에도 안 쓰는 데이터가 계속 쌓이면 공간이 모자라집니다. 가비지 컬렉션이 주기적으로 돌면서 “이건 아직 쓰이나? 이건?” 확인하고, 안 쓰이는 것을 정리합니다.

이 과정에서 앱이 잠깐 멈추는 경우가 있습니다. 가비지 컬렉션이 돌아가는 동안 앱의 실행이 일시 중단될 수 있기 때문입니다. 스마트폰이 간헐적으로 미세하게 버벅이는 원인 중 하나가 이것입니다.

참고로 모든 프로그래밍 언어에 가비지 컬렉션이 있는 것은 아닙니다. C나 C++ 같은 언어는 프로그래머가 직접 메모리를 관리합니다. 책상 위를 누가 치워주는 게 아니라, 본인이 알아서 정리해야 하는 겁니다. 실수로 안 치우면 메모리가 새는 메모리 누수(Memory Leak) 가 발생하고, 이미 치운 것을 또 치우려 하면 프로그램이 죽습니다. 자유가 큰 대신 위험도 큰 방식입니다.


사건: 1970년 1월 1일로 시간을 돌리면

2016년 2월, 아이폰 사용자들 사이에 소문이 돌았습니다.1

“날짜를 1970년 1월 1일로 설정하면 특별한 이스터에그가 나온다.”

이스터에그는 없었습니다. 대신 폰이 벽돌이 되었습니다. 전원을 꺼도, 다시 켜도, 아무것도 할 수 없는 상태. 복구하려면 애플 서비스 센터에 가야 했습니다.

왜 하필 1970년 1월 1일일까요?

컴퓨터는 시간을 숫자로 저장합니다. 1970년 1월 1일 자정을 기준점으로 삼고, 그 이후 흐른 초(秒) 수를 세는 방식입니다. 이걸 유닉스 시간(Unix Epoch) 이라고 합니다.

1970년 1월 1일 00:00:00  →  0
1970년 1월 1일 00:00:01  →  1
1970년 1월 2일 00:00:00  →  86,400
2026년 2월 14일           →  약 1,771,027,200

날짜를 1970년 1월 1일로 설정하면 이 값이 0이 됩니다. 문제는 시간대(타임존) 보정 과정에서 이 값이 0 아래로 — 음수로 — 내려갈 수 있다는 것입니다. 한국은 UTC+9이므로, 1970년 1월 1일 0시(한국 시각)는 유닉스 시간으로 -32,400이 됩니다. 시스템이 이 음수를 처리하지 못하면서 계산이 폭주한 것입니다.

이 사건은 “컴퓨터가 시간을 어떻게 다루는가“를 보여주는 사례입니다. 그리고 이 방식에는 유통기한이 있습니다.

2038년 문제

유닉스 시간은 전통적으로 32비트 정수로 저장됩니다. 32비트 정수의 최대값은 2,147,483,647. 이 숫자에 해당하는 날짜가 2038년 1월 19일 03:14:07(UTC) 입니다.

이 시점을 넘어가면? 숫자가 넘쳐서(오버플로) 음수가 됩니다. 컴퓨터가 갑자기 1901년 12월 13일로 되돌아간 것으로 인식할 수 있습니다.2

2038년 1월 19일 03:14:07  →  2,147,483,647 (32비트 최대)
2038년 1월 19일 03:14:08  →  -2,147,483,648 (오버플로!)
                              → 1901년 12월 13일로 해석

2000년을 앞두고 전 세계가 공포에 떨었던 Y2K 문제의 후속편입니다. Y2K는 연도를 두 자리로 저장해서 생긴 문제였고, 2038년 문제는 시간을 32비트로 저장해서 생기는 문제입니다. 대부분의 현대 시스템은 이미 64비트로 전환했지만, 오래된 임베디드 시스템3 — ATM, 산업용 장비, 자동차 ECU4 — 중에는 아직 32비트를 쓰는 것들이 남아 있습니다.


알쓸신잡

  • 왜 컴퓨터는 0부터 셀까?: 프로그래밍에서 배열의 첫 번째 칸은 1번이 아니라 0번입니다. 이건 메모리 주소 계산과 관련이 있습니다. “시작 위치에서 얼마나 떨어져 있는가“를 나타내는 것이기 때문에, 첫 번째 칸은 시작 위치에서 0만큼 떨어진 곳 — 0번입니다. 이것 때문에 프로그래머들은 “첫 번째“를 0이라고 부르는 습관이 있습니다. 1월 1일을 “0일“이라고 부르지는 않지만, 엘리베이터 층수는 유럽에서 0층부터 시작합니다.

  • 블루스크린(BSOD)의 정체: 윈도우에서 파란 화면에 흰 글씨가 뜨면서 컴퓨터가 멈추는 현상. 정식 명칭은 “Blue Screen of Death”. 운영체제가 더 이상 안전하게 실행할 수 없는 오류를 만났을 때 나타납니다. “이대로 계속 실행하면 데이터가 망가질 수 있으니, 차라리 멈추겠다“는 운영체제의 판단입니다. 2024년 CrowdStrike 사태 때 전 세계 공항, 병원, 은행의 윈도우 컴퓨터에 이 파란 화면이 동시에 떴습니다. 이 이야기는 3장에서 다시 만납니다.

  • 앱 강제종료, 자주 하면 좋을까?: 결론부터 말하면, 대부분의 경우 의미가 없습니다. 운영체제가 알아서 메모리를 관리하고 있기 때문입니다. 오히려 강제종료 후 다시 열면 서랍에서 꺼내오는 과정을 처음부터 다시 해야 하므로, 배터리와 시간이 더 들 수 있습니다. 앱이 응답하지 않거나 오작동할 때만 쓰는 것이 맞습니다.

배달앱이 실행되었고, 화면에 검색창이 떴습니다. “치킨“이라고 입력하고 검색 버튼을 누릅니다. 이 데이터는 이제 스마트폰 밖으로 나가야 합니다. 그런데 주머니 속 이 작은 기계에서 데이터가 어떻게 밖으로 나갈까요? 선은 연결되어 있지도 않은데 말입니다.



  1. iOS 8/9의 64비트 기기에서 발생. Apple이 iOS 9.3에서 수정. — 9to5Mac

  2. Year 2038 problem. 대부분의 현대 OS는 64비트 시간으로 전환 완료. — Wikipedia

  3. 임베디드 시스템(Embedded System): 특정 기능만 수행하도록 만들어진 소형 컴퓨터. ATM, 가전제품, 산업용 장비 등에 내장되어 있다.

  4. ECU(Electronic Control Unit): 자동차의 엔진, 브레이크 등을 제어하는 소형 컴퓨터.