사전 런타임
용어함정

런타임

gabury1고친 사람 github-actions[bot]

런타임은 프로그램이 돌고 있는 동안을 가리키는 말입니다. 그런데 같은 말이 그 동안을 떠받치는 소프트웨어도 가리킵니다. 도는 데 걸린 시간의 길이를 가리키기도 합니다. 어느 쪽 이야기인지 갈라야 뜻이 정해집니다.

쉽고 빠른 이해

무슨 일을 하는 물건인가 — 런타임은 한 물건에 붙은 이름이 아닙니다. 프로그램이 도는 동안과 얽힌 세 가지가 같은 이름을 씁니다. 「런타임 에러」의 런타임은 때를 말합니다. 「자바 런타임을 설치한다」의 런타임은 깔아서 쓰는 소프트웨어를 말합니다. 「이 정렬의 런타임」은 도는 데 걸린 시간을 말합니다.

왜 이렇게 하나 — 세 쓰임이 다 살아 있어서 어느 하나로 정할 수가 없습니다. 표기 규범 문서도 셋을 한 표제어 아래 나란히 적어 둡니다. 읽는 사람이 그때그때 갈라 읽어야 합니다.

어떻게 도나

  1. 「런타임에」처럼 조사가 붙어 있으면 때를 말하는 것입니다
  2. 「자바 런타임」처럼 앞에 언어나 제품 이름이 붙어 있으면 소프트웨어입니다
  3. 「런타임이 길다」처럼 길이를 재고 있으면 걸린 시간입니다

대가 — 낱말 하나로는 뜻이 안 서서 앞뒤 문장을 같이 봐야 합니다. 익숙한 뜻 하나로 밀어붙이면 엉뚱하게 읽습니다.

상세

런타임이라는 말이 가리키는 세 쓰임을 개관합니다. 근거는 둘입니다. 언어 표준이 가른 두 환경, 그리고 표기 규범이 한 표제어 아래 나란히 적어 둔 세 쓰임입니다.

런타임은 영어 runtime 을 옮긴 말입니다. 그중 하나가 프로그램이 돌고 있는 동안입니다. 프로그램을 켜서 끄기까지의 동안을 가리킵니다. 결제 서버를 띄워 두고 요청을 받고 있는 동안이 그 서버의 런타임입니다.

이 동안은 프로그램을 만드는 동안과 다릅니다. C 언어 표준은 개념 모형을 둘로 갈라 놓았습니다. 소스 코드를 실행할 수 있는 형태로 옮기는 환경이 하나, 그렇게 옮겨 놓은 것을 돌리는 환경이 다른 하나입니다. 돌리는 환경에서는 정해진 함수가 불리면서 프로그램이 시작됩니다. 프로그램이 끝나면 제어가 그 환경으로 돌아갑니다. 표준은 운영체제가 없는 경우까지 따로 정해 둡니다. 운영체제의 도움 없이 프로그램이 도는 환경을 독립 환경이라고 부릅니다.

마이크로소프트 표기 규범 문서는 runtime 이라는 한 표제어 아래 세 쓰임을 나란히 적어 둡니다. 기계어로 컴파일되지 않은 앱을 돌리는 데 필요한 환경이 하나, 애플리케이션이 도는 동안이 둘, 그 동안에 일어나거나 그 동안과 관계있는 것을 꾸미는 형용사가 셋입니다.

아래 「맥락별 뜻」이 쓰임을 하나씩 짚고 맥락마다 출처를 따로 답니다.

맥락별 뜻

런타임이 어느 세계의 글에서 무엇을 가리키는지를 맥락 셋으로 갈라 적습니다. 맥락마다 1급 문서를 따로 댑니다. 재는 것은 세 뜻을 서로 바꿔 쓸 수 있는지입니다. 못 바꿉니다.

맥락 이 맥락에서의 뜻 출처
언어 표준 프로그램이 돌고 있는 때. 옮기는 때와 맞세워 쓴다 C 언어 표준 §5.1 개념 모형 · 자바 언어 명세 11장·12장
제품과 배포 프로그램이 도는 동안 뒤에서 떠받치는 소프트웨어 오라클 자바 플랫폼 개요 · OCI(Open Container Initiative, 오픈 컨테이너 이니셔티브) 런타임 명세 · Go runtime 패키지 문서 · Node.js 소개
알고리즘과 측정 프로그램이나 절차가 도는 데 걸린 시간. 이 세계가 쓰는 표기는 running time 과 execution time 이다 Jeff Erickson, Algorithms 0장 · 파이썬 timeit 문서

어느 뜻이 원래 뜻이었는지는 자료에 없습니다(미확인).

프로그램이 도는 때라는 뜻

첫째 뜻은 때입니다. 이 뜻은 혼자 서지 않습니다. 소스 코드를 실행할 수 있는 형태로 옮기는 동안, 곧 컴파일 타임과 짝으로 섭니다. 런타임은 그렇게 옮겨 놓은 것을 돌리는 동안입니다.

둘을 가르는 까닭은 무엇이 언제 드러나는지가 다르기 때문입니다. 그 이유는 자바 쪽에 적혀 있습니다. 자바는 예외를 둘로 가릅니다. 한쪽이 검사 예외입니다. 메서드가 던질 수 있다고 미리 선언해야 하고, 컴파일러가 그 선언을 검사하는 예외입니다.

다른 한쪽은 검사하지 않는 예외입니다. 이쪽은 둘로 이뤄집니다. RuntimeException 과 그 아래 클래스들이 하나이고, 에러 클래스들이 다른 하나입니다. 이 두 묶음이 컴파일 타임 검사에서 면제됩니다.

면제하는 까닭도 같은 문서에 적혀 있습니다. 자바 컴파일러가 얻을 수 있는 정보와 컴파일러가 하는 분석 수준으로는 그런 예외를 미리 가려내기에 대개 충분하지 않습니다. 자바를 설계한 사람들의 판단으로는, 그런 예외까지 선언하게 해도 프로그램이 맞다는 것을 세우는 데 크게 도움이 되지 않습니다.

그래서 돌리는 동안에야 드러나는 오류를 런타임 에러라고 부릅니다. 자바는 RuntimeException 과 그 하위 클래스들을 묶어 run-time exception classes 라고 부릅니다.

두 때의 앞뒤는 이렇습니다. 위쪽 상자 안에서 하는 일과 아래쪽 상자 안에서 하는 일이 갈립니다.

flowchart TD
    subgraph CT["컴파일 타임 · 옮기는 동안"]
        A["소스 코드"] --> B["컴파일러가 검사하고 옮긴다"]
        B --> C["실행할 수 있는 형태"]
    end
    C --> D
    subgraph RT["런타임 · 돌리는 동안"]
        D["프로그램을 켠다"] --> E["명령을 하나씩 실행한다"]
        E --> F["검사에서 면제된 예외가 여기서 터진다"]
    end

「런타임에 정해진다」는 말도 이 뜻입니다. 자바에서 링킹은 클래스의 바이너리 형태를 자바 가상 머신의 실행 중 상태에 합쳐 넣는 과정입니다. 클래스 안의 이름으로 된 참조를 언제 풀지는 구현이 고릅니다. 쓰일 때 하나씩 풀 수도 있고, 검증하는 동안 한꺼번에 풀 수도 있습니다. 그래서 어떤 구현에서는 클래스가 초기화된 뒤에도 푸는 일이 이어질 수 있습니다.

실행을 떠받치는 소프트웨어라는 뜻

둘째 뜻은 물건입니다. 프로그램이 도는 동안 뒤에서 돌봐 주는 소프트웨어를 런타임이라고 부릅니다. 길게는 런타임 시스템이라고 합니다. 앞에 언어나 제품 이름을 붙여 「자바 런타임」· 「컨테이너 런타임」처럼 부릅니다.

자바에서 이 몫을 맡는 것이 JRE(Java Runtime Environment, 자바 실행 환경)입니다. 오라클은 JRE 가 자바로 쓴 애플릿과 애플리케이션을 돌리는 데 필요한 라이브러리와 자바 가상 머신, 그 밖의 구성 요소를 준다고 적습니다. 이 실행 환경은 애플리케이션과 함께 재배포해서 그 애플리케이션이 홀로 서게 할 수 있습니다.

컨테이너 세계에서는 OCI 런타임 명세가 런타임의 책무를 동작 목록으로 못 박아 두었습니다. 런타임은 번들에서 설정 파일을 읽습니다. 번들은 컨테이너 하나를 만드는 데 필요한 설정 파일을 담은 것이고, 런타임의 create 명령은 그 번들이 어디 있는지를 가리키는 값을 받습니다. 런타임은 읽어 들인 정보로 컨테이너를 만들고, 컨테이너 안에서 프로세스를 띄우고, 그 밖의 생애주기 동작을 수행합니다. 컨테이너가 만들어져 사라지기까지의 상태 이름도 같은 문서가 정해 둡니다.

stateDiagram-v2
    [*] --> creating: 런타임의 create 명령
    creating --> created: 요청한 자원을 다 만들었다
    created --> running: 사용자가 지정한 프로그램을 실행했다
    running --> stopped: 컨테이너 프로세스가 끝났다
    stopped --> [*]

이 명세는 도커와 쿠버네티스를 런타임이라고 부르지 않습니다. 둘에게는 런타임을 부르는 쪽이라는 이름이 따로 붙어 있습니다. containerd 와 Podman 이 직접 부르는 쪽이고, 도커와 쿠버네티스는 그 부르는 쪽을 거쳐 가는 간접으로 부르는 쪽입니다. 런타임이라고 불리는 것은 그 구현체 하나뿐입니다.

flowchart TD
    subgraph IND["간접으로 부르는 쪽"]
        D["도커 · 쿠버네티스"]
    end
    subgraph DIR["직접 부르는 쪽"]
        C["containerd · Podman"]
    end
    subgraph RTS["런타임 · 명세를 구현한 물건"]
        R["설정 파일을 읽고 컨테이너를 만든다"]
    end
    D --> C
    C --> R
    R --> K["컨테이너"]

언어가 자기 안에 런타임 시스템을 두기도 합니다. Go 의 runtime 패키지 문서는 자기를 Go 런타임 시스템과 상호작용하는 연산들을 담은 패키지라고 소개합니다. 고루틴을 제어하는 함수가 그런 연산입니다. 가비지 컬렉션도 이 런타임 시스템의 몫이라서, GOGC 환경 변수로 수거를 시작하는 처음 기준을 정하거나 아예 끌 수 있습니다.

자바스크립트 쪽에서는 Node.js 가 자기를 비동기 이벤트 기반 자바스크립트 런타임이라고 소개합니다. 이 뜻일 때 런타임은 깔고 배포하는 물건입니다. 「런타임을 깔아라」는 이 이야기입니다.

프로그램이 도는 데 걸린 시간이라는 뜻

셋째 뜻은 시간의 길이입니다. 프로그램이나 절차 하나가 도는 데 걸리는 시간을 재는 세계가 따로 있습니다. 알고리즘을 다루는 글과 시간을 재는 도구가 거기 있습니다.

다만 이 세계가 쓰는 표기는 런타임 한 낱말이 아닙니다. Jeff Erickson 의 알고리즘 교재는 running time 이라고 적고, 파이썬 표준 라이브러리의 timeit 문서는 execution time 이라고 적습니다. 우리말로 옮기면 수행 시간과 실행 시간입니다.

그 교재의 0장이 이 시간을 무엇으로 재는지 보입니다. 교재는 n 절짜리 노래를 부르는 데 걸리는 시간을 예로 듭니다. 그 시간은 n 의 함수이면서 부르는 사람과 매체에 따라서도 달라집니다.

어떻게 부르나 한 절에 걸리는 시간
어떤 가수가 부른다 10초
다른 가수가 부른다 20초
모스 부호 전신으로 받아 적게 한다 1분
같은 노래를 mp3 로 내려받는다 0.1초
mp3 를 메모리 안에서 복제한다 몇 마이크로초

교재가 중요하다고 짚는 것은 그 절대값이 아닙니다. n 이 커질 때 시간이 어떻게 변하는가 입니다. 절을 두 배로 늘리면 부르는 시간도 대략 두 배가 됩니다. 입력이 커질 때 수행 시간이 어떻게 늘어나는지를 재는 것이 시간 복잡도입니다.

재는 도구 쪽도 같은 것을 잽니다. timeit 은 자기를 작은 코드 조각의 실행 시간을 재는 모듈이라고 소개합니다. 명령줄로도 쓰고 코드에서 불러서도 씁니다. 시간 측정에서 흔히 빠지는 함정 여럿을 피해 준다고 적혀 있습니다. 이 맥락의 시간은 깔아서 쓰는 소프트웨어와 아무 관계가 없습니다.

어느 뜻인지 가르는 단서

셋 중 어느 뜻인지는 앞뒤 낱말이 알려 줍니다.

문장 꼴 어느 뜻인가 읽는 법
런타임에 · 런타임 에러 · 런타임 검사 때 돌리는 동안에 그렇다는 말
자바 런타임 · 컨테이너 런타임 · 런타임 설치 물건 떠받치는 소프트웨어를 가리키는 말
런타임이 길다 · 런타임을 잰다 걸린 시간 도는 데 걸린 시간을 말하는 것

가운데 줄이 헷갈리기 쉽습니다. 앞에 언어나 제품 이름이 붙어 있으면 물건이라고 보면 대개 맞습니다.

배경

런타임이 때가 아니라 코드 묶음을 가리키는 쓰임이 어디서 나오는지 봅니다. 컴파일러가 프로그램에 함께 얹어 주는 지원 코드를 가지고 봅니다.

우리가 쓴 코드에는 없는데 프로그램에 필요한 일이 있습니다. 대상 프로세서가 직접 못 하는 연산이 그렇습니다. 어떤 기계는 정수 곱셈과 나눗셈을 못 합니다. 어떤 기계는 부동소수점과 고정소수점 연산 전부를 못 합니다.

GCC(GNU Compiler Collection, GNU 컴파일러 모음)는 그 자리에 코드를 펼쳐 넣기에는 너무 복잡한 동작이 필요할 때마다, 저수준 런타임 라이브러리인 libgcc 의 루틴을 부르는 코드를 스스로 끼워 넣습니다. 예외 처리 루틴도 이 라이브러리에 들어 있습니다. memcpy 나 memset 같은 C 라이브러리 루틴 호출도 경우에 따라 만들어 넣습니다. 결과로 프로그램에는 우리가 안 쓴 코드가 함께 얹혀 돌아갑니다.

flowchart TD
    subgraph PROG["돌아가는 프로그램 한 덩이"]
        MY["내가 쓴 코드"]
        CALL["컴파일러가 끼워 넣은 호출"]
        subgraph LIB["libgcc 루틴"]
            R1["정수 곱셈 · 나눗셈"]
            R2["부동소수점 · 고정소수점 연산"]
            R3["예외 처리"]
        end
        MY --> CALL
        CALL --> LIB
    end

GCC 문서는 이렇게 함께 얹히는 코드 묶음을 런타임 라이브러리라고 부릅니다. 런타임이 때가 아니라 한 덩어리 물건을 가리키는 쓰임이 여기 있습니다. 언제부터 이 말을 그렇게 썼는지는 자료에 없습니다(미확인).

띄어쓰기로 뜻을 가르려는 시도는 어긋납니다. 마이크로소프트 표기 규범은 세 쓰임 모두 runtime 한 낱말로 붙여 쓰라고 정합니다. 그런데 자바 언어 명세는 한 장 안에서 run-time exception classes 와 RuntimeException 을 같이 씁니다. Go 문서도 runtime system 과 run-time type system 을 같이 씁니다. 표기가 아니라 앞뒤 문장이 뜻을 정합니다.

경계

「자바 런타임」이 어느 배포물을 가리키는지 하나만 판정합니다. 판정의 바탕은 오라클이 자바 플랫폼의 구성 요소들을 어떻게 갈라 적었는가입니다.

「자바 런타임을 깔아라」의 런타임은 JDK·JRE·JVM 중 무엇인가. JRE 입니다.

오라클은 자바 플랫폼 표준판에 주된 소프트웨어 제품 둘을 둡니다. 하나가 JRE 이고 다른 하나가 JDK(Java Development Kit, 자바 개발 키트)입니다. JRE 는 자바로 쓴 애플릿과 애플리케이션을 돌리는 데 필요한 라이브러리와 자바 가상 머신, 그 밖의 구성 요소를 줍니다. JDK 는 거기에 컴파일러와 디버거 같은 명령줄 개발 도구를 더한 것입니다. JVM(Java Virtual Machine, 자바 가상 머신)은 명령어 집합을 갖고 돌리는 동안 메모리를 다루는 추상 계산 기계입니다.

flowchart TD
    subgraph JDK["JDK · 개발까지 하는 배포물"]
        subgraph JRE["JRE · 돌리는 데 필요한 것만 담은 배포물"]
            JVM["JVM · 명령어를 실행하는 추상 기계"]
            LIB["클래스 라이브러리"]
        end
        TOOL["컴파일러 · 디버거 같은 개발 도구"]
    end

판정의 근거는 「깐다」는 말에 있습니다. 돌리기만 하면 되는 쪽이 까는 배포물은 JRE 입니다. JDK 는 개발 도구까지 담아 그보다 큽니다. JVM 은 JRE 안에 든 구성 요소 하나라서 까는 물건 전체를 가리키지 못합니다.

관련 항목

이것과 맞세워지는 시점과 그때 도는 도구

컴파일 타임 · 컴파일러 · 링커 · 빌드 · 정적 분석

언어마다 실행을 떠받치는 런타임 소프트웨어

JRE · JVM · Node.js · CLR · Go 런타임 · Python 인터프리터

컨테이너를 실제로 띄우는 런타임 구현체

컨테이너 런타임 · containerd · runc · Podman · 도커 · 쿠버네티스

런타임 시스템이 프로그램 대신 맡는 관리 기능

가비지 컬렉터 · 메모리 할당 · 예외 처리 · 스레드 스케줄링 · 동적 링크 · 런타임 라이브러리

돌리는 동안에만 드러나는 오류

런타임 에러 · NullPointerException · 세그멘테이션 폴트 · ClassNotFoundException · 스택 오버플로

돌리는 동안에 정해지는 것을 다루는 개념

동적 바인딩 · 리플렉션 · 다형성 · 인터프리터 · JIT 컴파일러

프로그램이 도는 데 걸린 시간을 재는 지표

시간 복잡도 · 수행 시간 · 지연 시간 · 프로파일링 · 벤치마크

런타임이 올라앉는 실행 바탕

운영체제 · 프로세스 · 스레드 · 가상 머신 · 시스템 콜

이것을 정의하는 표준·명세 문서

C 표준 · 자바 언어 명세 · OCI 런타임 명세 · 소스 코드 · 바이트코드

다른 이름: runtime · run time · running time · 실행 시간 · 실행 환경