티스토리 뷰

TIL/Java

JDK 21, Virtual Thread 정리

DandyU 2025. 1. 3. 10:41

1. Virtual Thread 소개

Virtual Thread는 JDK 21에 정식 Feature로 추가된 경량 스레드로, OpenJDK의 Project Loom에서 개발되었습니다. 이 프로젝트는 Java의 동시성 (Concurreny) 처리 개선을 목표로 2017년에 시작되었습니다.

 

2. Thread와 Virtual Thread의 구조

Java의 Thread는 OS의 Kernel Thread에 1:1 구조로 Thread 생성 시 JNI를 통해 OS에 Kerner Thread가 생성됩니다. 생성된 Thread는 OS에 의해 스케줄링됩니다.

Thread

 

Virtual Thread는 Carrier Thread에 1:N 구조로 여러 Virtual Thread를 하나의 Carrier Thread에 돌아가면서 실행됩니다. 생성된 Virtual Thread는 JVM에 의해 스케줄링됩니다.

Virtual Thread

 

 

3. Thread와 비교 시 Virtual Thread의 개선점

  • Thread의 생성과 관리 비용을 개선
    • OS의 Kernel Thread는 OS에 의해 생성되고 스케줄링되어 CPU에서 실행됩니다.
    • JVM은 JNI를 통해 Kernel Thread를 제어합니다.
    • 이러한 구조는 Thread의 생성과 Context Switching 시 높은 비용이 발생합니다.
    • Virtual Thread는 JVM 내부에서 Virtual Thread의 생성과 스케줄링을 직접 관리합니다.
  • Thread의 메모리 사용량을 개선
    특성 Thread Virtual Thread
    초기 메모리 약 1MB(기본 스택 크기) 약 몇 KB(필요에 따라 증가)
    최대 메모리 스택 크기 고정 스택 크기 동적 증가
    Thread 수 제한적(메모리 소모가 큼) 수백만 개 생성 가능
    .
  • 제한된 개수만 생성 가능한 Thread를 개선
    • Thread는 OS의 Kernel Thread를 1:1로 Wrapping한 Platform  Thread입니다.
    • OS의 Kernel Thread는 OS에서 관리되고 생성 개수가 제한되어 있어, Thread 역시 생성이 제한적입니다.
    • Virtual Thread는 OS의 Kernel Thread와 1:1 Wrapping 되지 않고
      JVM 내부에서 관리되기 때문에 Heap 범위 내에서 제한 없이 많은 Virtual Thread의 생성이 가능합니다.
  • 블로킹 I/O 처리 시 Thread의 대기 상태를 개선
    • Thread는 블로킹 I/O 작업 시 대기 상태로 전환되고, 작업이 완료될 때까지 다른 작업을 처리할 수 없습니다.
    • Idle 상태의 Thread가 생깁니다.
    • Virtual Thread는 블로킹 I/O 작업 시 Carrier Thread에서 Unmount되고, 다른 Virtual Thread가 해당 Carrier Thread에 Mount되어 Carrier Thread는 Idle 상태가 되지 않고 계속 동작하게 됩니다.


4. Coroutine(비동기 프로그래밍)과 비교 시 Virtual Thread의 장점

  • 제어 흐름 유지
    • 비동기 프로그래밍에서는 조건문이나 반복문과 같은 단순한 제어 흐름을 구현할 때 복잡한 코드 구조가 발생할 수 있습니다.
    • Callback 지옥과 같은 문제로 인해 부가적인 코드가 많아질 수 있습니다.
    • Virtual Thread를 사용하면 이러한 코드를 동기식으로 간단하게 작성 가능하게 해줍니다.
  • Context 유지
    • 비동기 프로그래밍은 요청이 여러 Thread를 넘나들며 처리되기 때문에 Context 정보가 스택 트레이스에 누적되지 않는 문제가 발생합니다.
    • 이로 인해 스택 트레이스가 쓸모가 없어집니다.
    • Virtual Thread는 Context를 유지하여 디버깅 및 문제 분석을 가능하게 해줍니다.

5. Continuation

Continuation은 Virtual Thread의 핵심 기술로, 프로그램 실행을 일시 중지하고 상태를 저장한 후, 저장된 상태를 다시 불러와 실행을 재개할 수 있게 해줍니다. 이를 통해 개발자는 동기식 코드 작성의 편리함을 유지하면서도 비동기 프로그래밍의 성능 이점을 얻을 수 있습니다.

 

6. 성능 테스트(by Spring Boot v3.4.1, JDK 21)

Tomcat Thread Pool 설정

server:
  tomcat:
    threads:
      max: 50 # 스레드 최대 생성 개수
      min-spare: 5 # Idle 상태의 스레드 개수
      
spring:
  threads:
    virtual:
      enabled: true # Virtual Thread 활성화/비활성화

 

테스트 코드

@RequiredArgsConstructor
@RestController
public class ThreadController {

    @GetMapping("/test-threads")
    public String testThreads() throws InterruptedException {
        Thread.sleep(1000); // 1초 Sleep

        return "Hello Java~";
    }

}

 

Virtual Thread On/Off에 따른 테스트 결과

  • Threads: 41.8 TPS
  • Virtual Threads: 72.4 TPS
  • Virtual Threads를 사용할 경우, TPS가 약 73% 증가하여 성능이 크게 향상되는 것을 확인할 수 있었다.
    하지만, 테스트는 성능 차이를 내기위해 극한(?)의 상황을 만들어 놓은거라 요청이 적은 환경은 이보다 적은 성능 향상을 확인할 수 있었다.

7. 유의사항

  • ThreadLocal 사용 시 메모리 증가 주의
    • Virtual Thread는 작업당 하나씩 생성하며, 각각 독립된 ThreadLocal 공간을 가집니다.
      의도치 않게 메모리 사용량이 증가할 수 있습니다.
    • 방안: 컨텍스트 전파가 필요한 경우 ScopedValue 또는 ThreadLocalAccessor 사용합니다.
  • Virtual Thread Pinning Issue(JDK 24에서 개선 예정)
    • synchronized 블록에 진입하면 Virtual Thread가 Carrier Thread에서 Unmount 못하는 상태(Pinning)가 발생하여
      성능 저하가 발생합니다.
    • 방안 : ReentrantLock 등 java.util.concurrent 패키지의 락 구현체를 사용합니다.
  • 과도한 동시성으로 인한 리소스 부족
    • DB Connection Pool 같은 제한된 자원에 동시 접근이 증가해 Timeout이 발생 가능합니다.
      (e.g: SQLTransientConnectionException)
    • 방안: Semaphore를 활용해 동시성을 제어하거나, Connection Pool 크기와 Virtual Thread 수를 적절히 조정하여 해결합니다.
  • CPU Bound 작업에는 비효율적
    • CPU Bound 작업은 Virtual Thread의 Mount/Unmount 오버헤드로 인해 Platform Thread보다 비효율적입니다.
    • 적합한 환경: IO Bound 작업에 효율적입니다.
  • Structured Concurrency 활용
    • 기존 CompletableFuture 체인은 작업 실패 시 리소스 누수나 에러 전파가 불명확합니다.
    • 방안: StructuredTaskScope를 사용해 작업 그룹의 생명주기를 명시적으로 관리합니다.

 

 

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함