Memory Optimization


🧰 1. Tối Ưu Hóa Bộ Nhớ (Memory Optimization)

✅ Tránh Escape to Heap không cần thiết

Escape analysis giúp Go xác định biến nên ở stack hay heap. Tránh escape nếu không cần thiết.

func NewUser() *User {
    user := User{}  // biến này escape sang heap vì được trả về con trỏ
    return &user
}

Tối ưu: nếu không cần con trỏ, dùng giá trị:

func Process(user User) { ... } // user nằm ở stack nếu đủ nhỏ

✅ Preallocate slice/map khi có thể

make([]int, 0, 1000)     // tránh reallocate khi append
make(map[string]int, 1000) // giảm chi phí rehash

⚙️ 2. Tối Ưu CPU và Goroutine

✅ Dùng worker pool thay vì tạo goroutine vô hạn

// xấu: tạo goroutine không kiểm soát
go func() { handle(request) }()

// tốt: dùng worker pool
jobs := make(chan Request, 100)
for i := 0; i < workerCount; i++ {
    go func() {
        for job := range jobs {
            handle(job)
        }
    }()
}

✅ Dùng sync.Pool để reuse object

var bufPool = sync.Pool{
    New: func() any {
        return new(bytes.Buffer)
    },
}

buf := bufPool.Get().(*bytes.Buffer)
defer bufPool.Put(buf)

🕵️ 3. Tối Ưu GC (Garbage Collector)

✅ Hạn chế tạo object không cần thiết trong hot path

  • Tránh string concatenation trong vòng lặp

  • Tránh interface{} nếu có thể – gây allocation và mất type info

✅ Dùng struct thay vì map nếu có schema cố định

// Tránh
map[string]interface{}{...}

// Tốt hơn
type Payload struct {
    ID   int
    Name string
}

🕸️ 4. Tối Ưu Concurrent Code

✅ Hạn chế mutex nếu không cần thiết

  • Dùng channel để giao tiếp nếu có thể

  • Nếu dùng sync.Mutex, đảm bảo vùng critical nhỏ nhất có thể

✅ Tránh deadlock, race condition

  • Luôn chạy với: go run -race main.go


📊 5. Dùng Profiler để đo, không đoán

✅ Tích hợp net/http/pprof

import _ "net/http/pprof"

go func() {
    log.Println(http.ListenAndServe("localhost:6060", nil))
}

Sau đó truy cập: http://localhost:6060/debug/pprof/

  • heap → memory

  • profile → CPU

  • goroutine → số lượng goroutine

✅ Dùng công cụ:

  • go tool pprof

  • benchstat, go test -bench, trace

  • golangci-lint → kiểm tra static code


🚀 6. Những Best Practices Khác

✅ Tránh reflection (reflect), trừ khi bất khả kháng

✅ Dùng const, iota thay vì magic string/number

✅ Tránh tạo interface nếu chỉ có một implementation


🧠 Kinh nghiệm thực chiến

Tình huống
Tối ưu hiệu quả

API latency cao

Giảm GC pressure, giảm object alloc

Worker CPU 100%

Profile goroutine leak hoặc contention

Tốn RAM nhiều

Check heap profile, object retention

Goroutine tăng liên tục

Có thể là leak hoặc không đóng channel


Last updated