코루틴은 왜 스레드보다 가벼울까?

김상진 ·2025년 5월 28일
0

CS

목록 보기
34/34
post-thumbnail

코루틴(Coroutine)은 백엔드 시스템에서 비동기 처리와 동시성 제어를 효율적으로 수행할 수 있게 해주는 경량 스레드 개념입니다. 전통적인 스레드 기반 처리 방식에 비해 메모리 사용, 컨텍스트 스위칭 비용, 관리 효율성에서 매우 가볍고 유연하다는 장점이 있습니다.


🔍 1. 메모리 사용량의 차이

🧵 스레드

  • 기본적으로 1MB의 스택 메모리가 필요합니다.
  • 스레드가 생성될 때 운영체제에 의해 고정된 크기의 메모리를 예약합니다.
  • 많은 스레드를 만들수록 시스템 메모리를 빠르게 소비합니다.

🌀 코루틴

  • 몇 KB 수준의 메모리만 사용합니다.
  • JVM 스레드 내부에서 실행되며 별도의 커널 리소스를 가지지 않습니다.
  • 수천 개의 코루틴도 문제없이 동시 실행 가능.

🔁 2. 컨텍스트 스위칭 비용

🧵 스레드

  • 컨텍스트 스위칭은 운영체제 커널 수준에서 수행되며 비용이 큽니다.
  • CPU 레지스터, 스택 포인터, 메모리 맵 등을 저장하고 복원하는 작업이 필요합니다.

🌀 코루틴

  • 사용자 공간(user space) 에서 가볍게 컨텍스트 전환이 이루어집니다.
  • 현재 위치(중단 지점)와 로컬 변수만 heap 메모리에 저장하면 됩니다.
  • 커널 레벨 개입이 없기 때문에 성능 오버헤드가 작습니다.

⚙️ 3. 생성 및 관리 비용

🧵 스레드

  • 스레드 생성은 OS에 시스템 호출을 필요로 합니다.
  • 커널 리소스를 포함한 무거운 오브젝트가 생성됩니다.

🌀 코루틴

  • 단순한 객체 생성 수준의 작업으로 관리됩니다.
  • 리소스 소비가 적고, 더 빠르게 생성 및 종료 가능.

⏸ 4. 일시 중단 방식의 차이

🧵 스레드

  • Thread.sleep() 같은 블로킹 호출은 스레드 전체를 대기 상태로 만듭니다.
  • 해당 스레드는 I/O 완료 전까지 아무 작업도 수행하지 못합니다.

🌀 코루틴

  • delay()스레드를 블로킹하지 않고, 코루틴만 일시 중단합니다.
  • 스레드는 다른 코루틴 실행에 재사용됩니다.
  • 수천 개의 코루틴을 수십 개의 스레드로 동시 처리 가능.

💡 5. 코드 예시로 비교

🧵 전통적 스레드 방식

for (i in 1..1000) {
    Thread {
        Thread.sleep(1000)
        println("Task $i completed")
    }.start()
}
// 약 1GB 이상의 메모리 사용

🌀 코루틴 방식

runBlocking {
    for (i in 1..1000) {
        launch {
            delay(1000)
            println("Task $i completed")
        }
    }
}
// 몇 MB의 메모리로도 충분

📚 추천 학습 자료


🧾 마무리 요약

비교 항목스레드(Thread)코루틴(Coroutine)
메모리 사용1MB 이상수 KB
생성 비용무거움 (OS 호출)가벼움 (객체 생성 수준)
컨텍스트 스위칭커널 개입, 고비용사용자 공간, 저비용
일시 중단전체 스레드 블로킹코루틴만 중단, 스레드 재활용

결론:
코루틴은 스레드보다 훨씬 가볍고, 효율적이며, 확장 가능한 동시성 처리를 가능하게 해주는 도구입니다. 특히 I/O 중심 백엔드 시스템에서는 비용 절감, 처리량 증가, 코드 간결성까지 기대할 수 있습니다.

사진 출처

profile
알고리즘은 백준 허브를 통해 github에 꾸준히 올리고 있습니다.🙂

0개의 댓글