JVM - OS 스레드 매핑

신지훈·2026년 3월 25일

JAVA/Spring/JVM

목록 보기
13/14

프로그램 vs 프로세스

프로그램 : 코드 덩어리
프로세스 : 코드 덩어리를 실행하기 위해 컴퓨터 자원을 할당 받은 상태

스레드

스레드는 프로세스 내에서 동시에 진행되는 작업의 갈래이자 실행 흐름의 단위이다.

백엔드 관점에서 보면 개발자가 서버를 실행할 때 JVM이라는 하나의 프로세스가 시작된다. 이때 운영체제(OS)는 이 JVM이 사용할 수 있도록 RAM 메모리의 일부를 떼어 전용 공간으로 할당해 준다.

출처

서버는 들어오는 요청을 스레드 단위로 처리한다. 그렇다면 JVM 내부에서 만든 스레드만으로 모든 연산을 완결 지을 수 있을까? 결론부터 말하자면 그렇지 않다. 그 이유는 메모리와 CPU의 자원 할당 방식 차이에 있다. OS는 RAM(메모리)의 경우 이만큼은 너의 전용 땅이다라고 공간을 점유하게 해주지만 CPU는 특정 프로세스에 영구적으로 떼어주지 않는다. CPU는 아주 짧은 시간씩 여러 프로세스를 번갈아 가며 지원하는 공유 자원이기 때문이다.
결국 JVM은 CPU를 직접 제어할 권한이 없으므로 연산이 필요할 때마다 OS의 핵심인 커널(Kernel)에 도움을 요청해야 한다. 이 메커니즘을 이해하기 위해 반드시 알아야 할 개념이 바로 유저 레벨 스레드와 커널 레벨 스레드이다.

커널 레벨 스레드, 유저 레벨 스레드

커널이란 하드웨어와 응용 프로그램 사이에서 CPU, 메모리, 주변 기기 등 시스템 자원을 제어하고 관리하는 핵심 소프트웨어이다.

앞서 언급했듯이 JVM은 CPU와 같은 물리적 자원을 직접 제어할 권한이 없다. 따라서 실제 연산 처리를 위해서는 자원 관리의 전권을 가진 커널의 힘을 빌려야 한다. 이를 단순하게 설명하면, JVM 내부에서 어떤 주소에 객체가 있고 뭘 만들고 어떤 연산을 해야하는지 등의 작업할 내용을 유저 레벨 스레드로 미리 정리해 둔 뒤 운영체제에 실행을 요청하는 시스템 콜(System Call) 을 보내는 방식이다. 요청을 받은 운영체제는 커널을 통해 실제 자원을 할당하여 작업을 해결한다.

이때 컴퓨터의 물리적 자원은 한정되어 있다. 따라서 커널 레벨 스레드 역시 무한정 생성할 수 없으며, JVM뿐만 아니라 컴퓨터 내의 다른 수많은 프로세스들과 함께 나누어 사용해야 한다. 이러한 제약 때문에 유저 레벨 스레드와 커널 레벨 스레드를 연결하는 적절한 매핑(Mapping) 과정이 필요하다. 매핑 방식에는 '1대 다', '1대 1', '다대 다' 등이 존재하는데, 일반적인 JVM 스레드의 경우 커널 레벨 스레드와 1대 1로 매핑(JDK 21 이전)되어 동작한다.

컨텍스트 스위칭

컨텍스트 스위칭을 이해하려면 CPU의 동시성 개념을 먼저 알아야 한다. 여기서 동시성이란 실제로 여러 일을 동시에 하는 것이 아니라 하나의 CPU가 A, B, C라는 여러 작업(스레드)을 아주 빠르게 번갈아 가며 처리하여 마치 동시에 실행되는 것처럼 보이게 하는 기술이다.

이렇게 작업의 주체를 교체하는 과정을 컨텍스트 스위칭이라고 한다. CPU가 현재 실행 중인 스레드 A에서 스레드 B로 넘어갈 때 단순히 바뀌는 것 뿐만 아니라 CPU는 나중에 다시 A로 돌아왔을 때 이전에 어디까지 작업했는지 기억하기 위해 현재 작업 상태(Context)를 어딘가에 기록해 두어야 한다.

중요한 점은 이 기록하고 불러오는 과정에서 비용이 발생한다는 것이다. 스레드가 너무 많아져서 컨텍스트 스위칭이 빈번하게 일어나면 CPU는 실제 연산을 하는 시간보다 작업의 상태를 갈아끼우는 데 더 많은 시간을 쓰게 된다. 이것이 바로 스레드를 무한정 늘린다고 해서 성능이 무조건 좋아지지 않는 결정적인 이유이다.

JVM이 실행 될때 JVM이 RAM에서 할당받은 메모리를 어떻게 사용하는지 알고 싶다면 런타임 데이터 영역(메모리 영역)을 참고하세요.

profile
주주주주니어 개발자

0개의 댓글