QUESTION #0308
백엔드

어떤 이유로 코루틴을 사용한 작업 처리가 기존 스레드 방식보다 가벼운지 설명해주세요.

어떤 이유로 코루틴을 사용한 작업 처리가 기존 스레드 방식보다 가벼운지 설명해주세요.

분야: 백엔드


메모리 사용량 차이

  • 스레드: 각 스레드는 자체 스택 메모리를 필요로 하며, JVM에서 기본적으로 약 1MB의 스택 크기를 할당합니다. 이 메모리는 스레드가 생성될 때 예약되며 스레드가 종료될 때까지 유지됩니다.
  • 코루틴: 코루틴은 스레드 내에서 실행되며 자체 스택을 필요로 하지 않습니다. 일반적으로 코루틴은 단지 몇 KB의 메모리만 사용합니다.

컨텍스트 스위칭 비용

  • 스레드: 스레드 간 전환은 운영체제 수준의 컨텍스트 스위칭을 필요로 하며, 이는 CPU 레지스터, 메모리 맵 등의 상태를 저장하고 복원하는 비용이 큽니다.
  • 코루틴: 코루틴 간 전환은 운영체제의 개입 없이 사용자 공간(user space)에서 발생하며, 단순히 실행 지점과 로컬 변수 상태만 heap 메모리에 저장하면 됩니다.

생성 및 관리 비용

  • 스레드: 새 스레드를 생성하는 것은 운영체제에 시스템 호출을 필요로 하며, 커널 수준의 리소스가 할당됩니다.
  • 코루틴: 코루틴 생성은 단순한 객체 할당과 유사하며, 운영체제 리소스를 직접 소비하지 않습니다.

일시 중단 메커니즘

  • 스레드: 스레드는 블로킹 작업(I/O 등) 중에는 완전히 차단되어 다른 작업을 수행할 수 없습니다.
  • 코루틴: 코루틴은 일시 중단 지점(suspend 함수)에서 실행을 중단하고 기본 스레드를 해제하여 다른 코루틴이 사용할 수 있게 합니다. 이로써 수천 개의 코루틴을 소수의 스레드에서 효율적으로 실행할 수 있습니다.

코드 예시로 비교

스레드 방식

// 1000개의 스레드를 생성하면 약 1GB의 메모리가 필요함
for (i in 1..1000) {
    Thread {
        // 각 스레드마다 작업 수행
        Thread.sleep(1000) // 스레드 블로킹
        println("Task $i completed")
    }.start()
}

코루틴 방식

runBlocking {
    // 1000개의 코루틴을 생성해도 몇 MB의 메모리만 사용
    for (i in 1..1000) {
        launch {
            // 각 코루틴마다 작업 수행
            delay(1000) // 코루틴만 일시 중단, 스레드는 다른 코루틴 실행 가능
            println("Task $i completed")
        }
    }
}

추가 학습 자료를 공유합니다.