Building a lower-latency GC
Bài tóm tắt Jane Street 2015 3. Quy mô lớn Độ khó: Khó
Jane Street · 2015 · 3. Quy mô lớn · Độ khó: Khó — bài gốc
Bối cảnh
- GC gây pause không đoán trước, xấu cho hệ giao dịch. Cách thường làm là pool hết object, không cấp phát gì trên đường nóng; cách này chạy được nhưng code khó viết và khó suy luận. Jane Street muốn một GC cho phép vẫn cấp phát mà latency vẫn thấp.
- GC của OCaml vốn khá tốt: major heap thu incremental theo lát, minor heap nhỏ (đo bằng MB, so với 5–10 GiB young generation hay khuyên cho Java). Vấn đề còn lại (theo bài): không có profiling từng pha; false promotion (object sắp chết bị đẩy lên major heap vì minor GC đến sai lúc); GC được "lên dây" theo lượng cấp phát chứ không theo thời gian, nên làm việc đúng lúc hệ bận; quét mảng lớn và GC root không incremental; khối lượng major slice tính ngay theo lượng promote của lần trước.
Thay đổi chính
Damien Doligez (tác giả GC của OCaml) làm việc tại Jane Street vài tháng, làm các nhánh thử nghiệm:
- Probe ghi chi tiết từng pha và pha con của GC.
- Aging ở minor heap: object sống qua vài lần minor GC rồi mới được promote.
- Incremental hơn: quét mảng và root có thể ngắt giữa chừng.
- Tách major slice khỏi minor GC: chạy riêng từng loại, vào lúc nào cũng được. Một job ở tầng ứng dụng định kỳ đoán xem hệ có rảnh không rồi tự lên lịch GC (minor chỉ khi minor heap đã lớn hơn ngưỡng để tránh false promotion).
- Kế toán công việc làm mượt: việc cần làm trải ra n slice tới trong một circular buffer; slice do ứng dụng ép chạy được trừ vào bucket đầu.
- Free list chia theo kích thước (đang làm).
Vì sao
- Kết quả 2015: dùng các thay đổi này cùng job ép major slice vào lúc rảnh, tail latency giảm 3 lần trên một ứng dụng production thật, gần như chưa tune tham số.
- Điểm đáng thất vọng: với batch job, aging gần như không cải thiện tổng thời gian tính (tiết kiệm promote nhưng minor GC đắt hơn), dù HotSpot, CLR, GHC đều có aging.
Bài học cho SWE
- Với hệ cần latency ổn định, câu hỏi là khi nào GC chạy chứ không chỉ chạy bao lâu: dời việc khỏi lúc bận sang lúc rảnh.
- Pool object là giải pháp được nhưng tốn công bảo trì; sửa runtime có thể trả lại sự dễ viết code.
- Đo từng pha trước khi tối ưu.
Liên quan
- Jane Street 2026 (đường nóng không cấp phát,
[@zero_alloc]) · Jane Street 2022 - Hệ thống độ trễ thấp (low latency) · Đổi ngôn ngữ và runtime
#OCaml GC#tail latency#object pooling#minor heap#false promotion#aging#incremental major slice#GC scheduling#smoothed work accounting#free list
Được nhắc tới trong
Công ty (1)