ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • golang: 런타임(Runtime)이란?
    Back-End/Golang 2024. 11. 27. 22:18
    반응형

    Go의 Runtime은 Go 프로그램의 실행을 관리하는 핵심 구성 요소입니다. 이는 Go 런타임이 제공하는 동작과 기능을 이해하면, 프로그램의 성능을 최적화하고 동작 방식을 효율적으로 활용할 수 있습니다. Go 런타임의 주요 구성 요소와 개념을 자세히 설명드리겠습니다.


    1. Go Runtime이란?

    Go의 런타임은 Go 프로그램이 실행되는 동안 메모리 관리, 병행성 처리, 가비지 컬렉션, 스케줄링 등의 작업을 담당하는 표준 라이브러리 및 런타임 시스템입니다.

    Go는 컴파일러 기반 언어로, C/C++처럼 런타임이 없는 언어에 가깝지만, 병행성과 메모리 관리 등의 기능을 위해 런타임 환경을 제공합니다.


    2. 주요 기능과 구성 요소

    2.1 가비지 컬렉터 (Garbage Collector)

    Go는 자동 메모리 관리를 위해 가비지 컬렉션(GC)을 제공합니다. 이는 프로그래머가 명시적으로 메모리를 해제하지 않아도 되도록 설계되었습니다.

    • 특징:
      • Mark-and-Sweep 알고리즘: 사용 중인 객체와 사용되지 않는 객체를 구분하여 정리.
      • 저지연(Low Latency): Go는 지연 시간을 최소화하면서 GC를 수행합니다.
      • 병렬 처리: GC는 병렬로 실행되며, 애플리케이션의 병행성을 방해하지 않습니다.
    • 최적화 팁:
      • 메모리 사용량을 줄이고, 불필요한 객체 생성을 피하세요.
      • Go 1.5 이후로 GC 성능은 GOGC 환경 변수로 제어 가능합니다
         
    GOGC=100 go run main.go

     

    • GOGC=100: 기본 설정.
    • GOGC=off: GC 비활성화.

    2.2 고루틴 (Goroutines)

    Go 런타임의 핵심은 고루틴(Goroutines)으로, 경량 스레드를 사용하여 동시성을 지원합니다.

    • 특징:
      • 고루틴은 기본적으로 함수 호출과 동일하게 시작되며, go 키워드로 생성됩니다.
      • 수백만 개의 고루틴을 실행해도 메모리 비용이 적게 듭니다.
      • 고루틴은 런타임 스케줄러에 의해 관리되며, OS 스레드와 1:N 매핑을 사용합니다.
    • 예제:
    func main() {
        go func() {
            fmt.Println("Hello from goroutine!")
        }()
        time.Sleep(time.Second)
    }

    2.3 런타임 스케줄러

    Go는 고루틴을 관리하기 위해 자체 스케줄러를 사용합니다.

    • M:N 스케줄링:
      • Go 스케줄러는 M개의 OS 스레드 위에 N개의 고루틴을 스케줄링합니다.
      • M: OS 스레드의 수.
      • N: 고루틴의 수.
    • 핵심 구성 요소:
      • G (Goroutine): 실행 중인 고루틴.
      • P (Processor): G와 M을 연결하며, 런타임 논리 프로세서 역할.
      • M (Machine): OS 스레드.
    • 작동 방식:
      • 고루틴은 P에 의해 실행되고, P는 OS 스레드(M) 위에서 동작합니다.
      • 고루틴이 블로킹되면 런타임은 다른 고루틴으로 교체합니다.

     


    2.4 채널 (Channels)

    Go 런타임은 고루틴 간 통신을 위한 채널을 제공합니다.

    • 특징:
      • 채널은 고루틴 간 데이터를 안전하게 전달합니다.
      • 기본적으로 동기화를 보장합니다.
    • 예제:
    func main() {
        ch := make(chan int)
        go func() {
            ch <- 42
        }()
        fmt.Println(<-ch)
    }

    2.5 동적 메모리 관리

    Go 런타임은 힙과 스택 메모리를 자동으로 관리합니다.

    • 스택:
      • 고루틴별로 독립적인 스택을 가집니다.
      • 스택은 런타임에 동적으로 확장 및 축소됩니다.
    • :
      • 동적으로 할당된 객체는 힙에 저장됩니다.
      • 가비지 컬렉터가 힙 메모리를 관리합니다.

    2.6 패닉과 복구 (Panic & Recover)

    Go 런타임은 패닉(panic)복구(recover) 메커니즘을 통해 런타임 오류를 처리합니다.

    • 패닉: 런타임 오류가 발생하면 프로그램이 패닉 상태에 진입합니다.
    • 복구: recover를 사용하면 패닉 상태를 복구할 수 있습니다.
    • 예제:
    func main() {
        defer func() {
            if r := recover(); r != nil {
                fmt.Println("Recovered from panic:", r)
            }
        }()
        panic("something went wrong")
    }

    2.7 runtime 패키지

    Go 런타임에 접근할 수 있는 기능을 제공하는 표준 라이브러리입니다.

    • 주요 함수:
      • runtime.GOMAXPROCS: 최대 사용할 CPU 코어 수 설정.
      • runtime.NumGoroutine: 현재 실행 중인 고루틴 수 반환.
      • runtime.Caller: 호출자 정보를 반환.
      • runtime.Callers: 호출 스택을 반환.

    3. Go 런타임의 장점

    1. 간결함:
      • C와 같은 낮은 레벨의 언어와 유사하면서도, 자동 메모리 관리 및 가비지 컬렉션을 통해 프로그래머의 부담을 줄입니다.
    2. 고성능 병행성:
      • 고루틴과 채널로 쉽고 강력한 병행성을 지원합니다.
    3. 안정성:
      • 타입 안전성, 가비지 컬렉션, 런타임 오류 처리로 안정적인 코드를 작성할 수 있습니다.

    4. 런타임의 제한점

    1. 가비지 컬렉션 오버헤드:
      • GC로 인해 성능이 완벽히 예측 가능하지 않을 수 있습니다.
    2. 스케줄러 오버헤드:
      • 고루틴의 수가 지나치게 많아지면 스케줄링 비용이 증가할 수 있습니다.

    5. 런타임 최적화 팁

    1. 메모리 관리:
      • 객체 수명을 줄이고, 힙 할당을 최소화하세요.
    2. 고루틴 관리:
      • 고루틴을 적절히 생성하고, 불필요한 고루틴을 방지하세요.
    3. GOMAXPROCS 설정:
      • CPU 코어를 효율적으로 사용하도록 조정하세요.
    runtime.GOMAXPROCS(runtime.NumCPU())

    요약

    Go의 런타임은 고루틴, 가비지 컬렉션, 메모리 관리, 런타임 스케줄러 등 다양한 기능으로 동시성과 성능을 효율적으로 처리합니다. 이 런타임 시스템을 이해하면 Go 프로그램을 더욱 안정적이고 효율적으로 작성할 수 있습니다.

    반응형
Designed by Tistory.