# Garbage Collection

***

### 🔥 1. Tổng Quan về Garbage Collection trong Go

Go là ngôn ngữ có **garbage collector (GC)** built-in, được thiết kế để:

* **Tự động quản lý bộ nhớ** (không cần `free()` như C/C++).
* **Tối ưu cho latency thấp**, không pause quá lâu.
* **Concurrent, Generational và Non-compacting** GC.

Từ Go 1.5 trở đi, GC của Go là **Concurrent Mark-and-Sweep**, được cải tiến qua từng version.

***

### 🧠 2. Cơ chế hoạt động của GC trong Go

#### Bước 1: **Mark Phase** (đánh dấu)

* Tìm tất cả các object đang được tham chiếu từ **root set** (global vars, stack vars...).
* Sử dụng **tracing GC** để theo dấu tất cả các object reachable.
* Được thực hiện **song song** với các goroutines.

#### Bước 2: **Sweep Phase**

* Dọn dẹp các object không còn được đánh dấu (unreachable).
* Bộ nhớ được trả về heap và có thể tái sử dụng.

#### Điểm đặc biệt:

* GC không **compacting**, nghĩa là không dời object trong heap (khác Java).
* Có **write barrier** để hỗ trợ marking trong khi chương trình đang chạy.

***

### ⚙️ 3. GC Tuning & Metrics

Go cho phép bạn theo dõi và điều chỉnh GC để phù hợp với use-case:

#### ⚙️ GC Parameters:

```go
debug.SetGCPercent(x) // x là % tăng heap mới trước khi trigger GC
```

* `SetGCPercent(100)` (default): Khi heap tăng 100% kể từ lần GC trước → trigger GC.
* `SetGCPercent(20)`: Dọn sớm hơn → latency thấp, nhưng CPU tốn hơn.

#### 🔍 GC Metrics:

```go
var memStats runtime.MemStats
runtime.ReadMemStats(&memStats)
fmt.Println(memStats.NumGC)              // Số lần GC
fmt.Println(memStats.PauseNs)            // Thời gian pause
fmt.Println(memStats.Alloc, memStats.HeapAlloc) // Dung lượng đang cấp phát
```

***

### 🛠️ 4. GC Performance Tuning trong Production

#### Mục tiêu: Tối ưu giữa **latency** và **throughput**.

**✅ Các chiến lược:**

* **Giảm cấp phát không cần thiết** (avoid unnecessary allocations).
  * Dùng `sync.Pool` cho object reuse.
  * Tránh tạo slice/map tạm thời trong hot path.
* **Giữ object nhỏ sống lâu trong stack thay vì heap**:
  * GC trong Go **không quét stack**, nếu object chỉ nằm trong stack → không phải dọn.
* **Prefetch bộ nhớ** (bằng warm-up request).

**✅ sync.Pool – một kỹ thuật rất hay:**

```go
var bufPool = sync.Pool{
    New: func() interface{} {
        return make([]byte, 4096)
    },
}

// Lấy từ pool
buf := bufPool.Get().([]byte)
// Xử lý
...
// Trả về pool
bufPool.Put(buf)
```

> Lợi ích: Giảm số lượng object GC phải xử lý → giảm áp lực GC.

***

### 🔥 5. High-level Concepts (Senior Level)

#### 📌 Write Barrier

* GC sử dụng "tri-color" marking: trắng (chưa mark), xám (chưa quét con), đen (quét xong).
* Write barrier giúp tránh "lost updates" khi chương trình đang cập nhật object trong lúc GC đang chạy.

#### 📌 GC Safe Points

* Điểm mà goroutine có thể safely bị dừng lại để phục vụ GC.
* Là lý do tại sao `for {}` mà không gọi hàm nào sẽ **không bao giờ trigger GC** (nó không có safe point).

#### 📌 Stack Scanning

* Go chỉ scan stack khi cần.
* Object nằm hoàn toàn trong stack không bị GC dọn, nhưng khi escape ra heap thì phải track.

***

### 🧪 6. Thực nghiệm GC – Đo và Debug

#### Dùng `GODEBUG` để bật debug log:

```bash
GODEBUG=gctrace=1 ./myprogram
```

Kết quả:

```
gc 1 @0.030s 2%: 0.16+1.2+0.016 ms clock, 0.32+0.31/0.99/2.3+0.032 ms cpu, 4->4->2 MB, 5 MB goal, 8 P
```

Giải thích:

* `0.16+1.2+0.016 ms`: Mark start, concurrent mark, mark termination
* `4->4->2 MB`: Heap size before GC, after mark, after sweep
* `5 MB goal`: Target heap size to next GC
* `8 P`: Số logical CPU (P = processors)

***

### 🧠 7. Khi nào nên lo về GC?

| Triệu chứng            | Có thể là do GC                       |
| ---------------------- | ------------------------------------- |
| Latency spikes         | Có thể là stop-the-world phase        |
| CPU usage tăng         | GC hoạt động quá thường xuyên         |
| Memory tăng không giảm | Object bị giữ reference (memory leak) |

***

### ✅ Tổng kết

| Kỹ thuật Go GC      | Ý nghĩa                          |
| ------------------- | -------------------------------- |
| `SetGCPercent`      | Điều chỉnh khi nào GC chạy       |
| `sync.Pool`         | Giảm cấp phát heap               |
| `MemStats`          | Theo dõi GC trong runtime        |
| `GODEBUG=gctrace=1` | Debug GC                         |
| Escape Analysis     | Tối ưu để giữ object trong stack |

***
