Khi dữ liệu còn sống gần chạm giới hạn heap, GC chạy xong cũng gần như không thu hồi được gì, nên GC cứ lặp lại không ngừng.
Vì sao Số người tăng do sự kiện hoặc rò rỉ bộ nhớ làm dữ liệu còn sống lấp gần tới giới hạn heap → Dẫn đến GC chỉ thu hồi được một ít nên lập tức lại chạy Full GC, phần lớn CPU bị GC chiếm → Trên màn hình Cả server lặp đi lặp lại quay chậm và đứng hình trong vài phút rồi sập vì hết bộ nhớ
Giờ cao điểm buổi tối, Khi đông người, Càng chạy lâu càng nặng
Phụ trách
Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)
Việc cần làm (Đội phát triển game)
Đặt heap rộng hơn hẳn lượng dữ liệu còn sống lúc cao điểm (thường từ 2 lần trở lên), giảm dữ liệu bị tham chiếu lâu và rò rỉ.
Việc cần làm (Đội hạ tầng)
Cảnh báo theo tỷ lệ thời gian GC, khởi động lại sớm thay vì cố cầm cự, dùng instance nhiều bộ nhớ để có thể tăng heap.
Con số tham khảo
Nếu GC chiếm hơn 10% thời gian chạy thì thường được coi là dấu hiệu nguy hiểm. Một số GC của Java báo lỗi hết bộ nhớ khi đã dành 98% thời gian cho GC mà vẫn gần như không thu hồi được gì.
Trên đồ thị
Chạm giới hạn rồi đi ngang · Heap ngay sau GC, tỷ lệ thời gian GC
Chỗ cần xem
Xem heap còn lại ngay sau GC gần mức heap tối đa đến đâu, và tỷ lệ thời gian dành cho GC. Java: “sau GC (kích thước heap)” trên dòng -Xlog:gc và tần suất dòng Pause Full; .NET: dotnet-counters (.NET 8 trở xuống là % Time in GC since last GC, .NET 9 trở đi là mức tăng của dotnet.gc.pause.time); Go: khoảng cách giữa các dòng GODEBUG=gctrace=1
Đúng nếu
ngay sau GC heap vẫn gần mức tối đa, Full GC chạy liên tiếp, tỷ lệ thời gian GC tăng mạnh so với bình thường (thường vượt 10%). Trong lúc đó tick của cả server cùng chậm đi
Loại trừ nếu
heap sau GC vẫn còn dư mà chỉ lần dừng kéo dài → do loại GC hoặc cấu hình GC (mem-gc)
Cách kiểm tra
Kiểm tra bằng công cụ hạ tầng (không cần code game)
Nguồn
The Parallel CollectorOracle Parallel GC báo OutOfMemoryError khi dành hơn 98% tổng thời gian cho GC mà thu hồi được dưới 2% heap
Garbage-First Garbage Collector TuningOracle Mặc định (GCTimeRatio=12), G1 chọn kích thước heap sao cho thời gian GC khoảng 8% tổng thời gian trở xuống; Full GC do heap bị chiếm quá nhiều được tìm trong log qua dòng Pause Full (G1 Compaction Pause)
A Guide to the Go Garbage CollectorGo Với mặc định GOGC=100, heap mục tiêu khoảng gấp 2 lần heap còn sống; khi bám sát giới hạn bộ nhớ, GC chạy không nghỉ (thrashing); GODEBUG=gctrace=1 in ra thông tin theo dõi GC
Garbage Collector ImplementationOracle Dòng -Xlog:gc gồm loại GC (Pause Young, Pause Full), “mức dùng trước GC->mức dùng sau GC (kích thước heap)” và thời gian dừng
dotnet-counters diagnostic tool.NET .NET 9 trở đi hiển thị là dotnet.gc.pause.time, .NET 8 trở xuống là % Time in GC since last GC