sync.Pool là kho tạm chứa các object có thể tái sử dụng, mục tiêu duy nhất là giảm số lần cấp phát và áp lực GC cho những object bị tạo ra rồi vứt đi liên tục — điển hình là buffer trong handler HTTP.
var bufPool = sync.Pool{
New: func() any { return new(bytes.Buffer) },
}
func handler(w http.ResponseWriter, r *http.Request) {
buf := bufPool.Get().(*bytes.Buffer)
buf.Reset() // bắt buộc: object lấy ra còn dữ liệu cũ
defer bufPool.Put(buf)
// ... dùng buf để dựng response
}Điều kiện dùng đúng:
- Object không mang state có ý nghĩa giữa các lần dùng; luôn Reset sau khi Get.
- Tần suất tạo/hủy cao và kích thước tương đối đồng đều.
- Không được giữ tham chiếu tới object (hoặc slice cắt từ nó) sau khi Put — đây là lỗi kiểu use-after-free, gây rò rỉ dữ liệu giữa các request.
Khi không nên dùng:
- Làm object pool cho tài nguyên đắt (kết nối DB, socket). sync.Pool không đảm bảo giữ lại object: GC có thể dọn sạch pool bất cứ lúc nào. Kết nối cần pool có vòng đời rõ ràng như database/sql.
- Object có kích thước dao động lớn — buffer khổng lồ bị giữ lại sẽ chiếm bộ nhớ; nên chỉ Put lại khi cap dưới ngưỡng.
- Chưa đo được vấn đề. Pool làm code phức tạp hơn và có chi phí đồng bộ riêng; chỉ thêm khi heap profile chỉ đúng vào chỗ cấp phát đó.