PHpullh
학습 라이브러리/Go/sync.Pool & 메모리 최적화

GO · 성능

sync.Pool & 메모리 최적화

임시 객체를 재사용하는 sync.Pool로 GC 압력을 줄입니다.

성능고급sync.PoolGC메모리최적화strings.Buildermake capacity

핵심 설명

임시 객체를 재사용하는 sync.Pool로 GC 압력을 줄입니다.

Go code

package main

import (
	"bytes"
	"fmt"
	"sync"
)

// sync.Pool — 임시 객체 재사용 (GC 시 해제될 수 있음)
var bufPool = sync.Pool{
	New: func() interface{} {
		return new(bytes.Buffer)
	},
}

func processRequest(data string) string {
	// 풀에서 버퍼 가져오기
	buf := bufPool.Get().(*bytes.Buffer)
	defer func() {
		buf.Reset()
		bufPool.Put(buf) // 풀에 반환
	}()

	buf.WriteString("처리: ")
	buf.WriteString(data)
	return buf.String()
}

// 슬라이스 미리 할당
func efficientAppend(n int) []int {
	// Bad: 매번 재할당
	// result := []int{}
	// for i := 0; i < n; i++ { result = append(result, i) }

	// Good: 미리 용량 할당
	result := make([]int, 0, n)
	for i := 0; i < n; i++ {
		result = append(result, i)
	}
	return result
}

// 문자열 변환 최적화
func buildString(parts []string) string {
	// Bad: + 연산자 (매번 새 문자열)
	// s := ""
	// for _, p := range parts { s += p }

	// Good: strings.Builder
	var sb strings.Builder
	sb.Grow(len(parts) * 10) // 예상 크기 예약
	for _, p := range parts { sb.WriteString(p) }
	return sb.String()
}

func main() {
	results := make([]string, 5)
	for i := 0; i < 5; i++ {
		results[i] = processRequest(fmt.Sprintf("req-%d", i))
	}
	for _, r := range results { fmt.Println(r) }

	nums := efficientAppend(100)
	fmt.Println("첫:", nums[0], "마지막:", nums[99])
}

학습 팁

sync.Pool은 GC 사이클에 의해 비워질 수 있습니다. 영구 캐시로 사용하지 마세요. 할당 비용이 큰 임시 객체(버퍼, 파서 등)에 적합합니다.

주의할 점

sync.Pool에서 꺼낸 객체는 반드시 Reset()하거나 초기화하세요. 이전 사용자의 데이터가 남아 있습니다.

자주 묻는 질문

sync.Pool & 메모리 최적화란 무엇인가요?

임시 객체를 재사용하는 sync.Pool 로 GC 압력을 줄입니다.

sync.Pool & 메모리 최적화 학습 시 주의할 점은 무엇인가요?

sync.Pool 에서 꺼낸 객체는 반드시 Reset() 하거나 초기화하세요. 이전 사용자의 데이터가 남아 있습니다.