728x90

Go 의 문서를 읽어보면 Goroutine 의 개수에 대해서 걱정하는 것은 섣부른 최적화 라고 나와 있을정도로 Goroutine은 가볍다고 나와 있다. 하지만 정말 수백 수천 만개의 고루틴 을 돌려도 메모리가 버틸수 있을 지 궁금했다.

 

이 예제는 Goroutine 이 가비지 컬렌셕되지 않는다는 사실과 런타임이 스스로 검사할수 있는 기능을 조합하여 고루틴 생성 전후에 할당된 메모리 양을 측정한다.

 

package main

import (
	"fmt"
	"runtime"
	"sync"
)

func main() {
	memConsumed := func() uint64 {
		runtime.GC()
		var s runtime.MemStats
		runtime.ReadMemStats(&s)
		return s.Sys
	}

	var c <-chan interface{}
	var wg sync.WaitGroup
	noop := func() { // 1
		wg.Done()
		<-c
	}
	const numGoroutines = 1e4 // 2
	wg.Add(numGoroutines)
	before := memConsumed() // 3
	for i := numGoroutines; i > 0; i-- {
		go noop()
	}
	wg.Wait()
	after := memConsumed() // 4
	fmt.Printf("%.3fkb", float64(after-before)/numGoroutines/1000)
}

 

1. 측정을 위해서 메모리상에 다수의 고루틴이 유지돼야 하며 이를 위해 고루틴이 절대로 종료되지 않도록 해야한다.

2. 여기서 생성할 고루틴의 수를 정의한다. 고루틴 하나의 크기에 점근적으로 접근하기 위해 대수의 법칙을 사용할 것이다.

3. 여기서는 고루틴들을 생성하기 전에 소비된 메모리 양을 측정한다.

4. 그리고 여기서 고루틴들을 생성한 후에 소비된 메모리 양을 측정한다.

 

결과는 다음과 같다.

 

이 예제의 고루틴들은 아무것도 하지않는 빈 고루틴이지만 고루틴을 몇개나 만들 수 있는지 암시한다.

 

나의 작은 m1 맥북에는 8GB 의 RAM 을 사용한다. 즉, 이론상으로는 스와핑 없이도 수백만개의 고루틴을 돌릴 수 있다.

물론 이 이론은 컴퓨터에서 실행중인 다른 프로그램과 고루틴의 실제 내용을 무시한 결과이지만 이 간단한 계산을 통해 고루틴이 얼마나 가벼운지 알수있다.

 

 

728x90

'Go' 카테고리의 다른 글

Linux Set up GO PATH  (0) 2021.11.07
Fibonacci 로 알아보는 동시성 과 클로저  (0) 2021.10.26
Publisher Subscriber pattern (발행 구독 패턴)  (0) 2021.10.25
Handling databases using gorm  (0) 2021.10.20
Go interface: 대소문자 의 의미  (0) 2021.10.20