Trong lúc thu hồi bộ nhớ đã dùng xong (rác), cả game dừng lại. Đặc trưng là giật khựng theo khoảng cách đều đặn.
Vì sao Mỗi khung hình đều tạo rồi bỏ các chuỗi, mảng, list tạm → Dẫn đến Rác dồn lại thì GC dừng main thread để thu hồi → Trên màn hình Cứ vài giây đến vài chục giây lại giật khựng đều đặn
Phụ trách chính Phát triển client (Đội phát triển game)
Việc cần làm (Đội phát triển game)
Giảm cấp phát (tránh nối chuỗi, LINQ, capture biến trong lambda), dùng object pool, bật incremental GC (mặc định từ Unity 2020), chủ động chạy GC vào lúc dừng cũng không sao, như màn hình loading.
Con số tham khảo
Thường mỗi lần mất vài ms đến 100 ms; trên điện thoại cấu hình thấp hoặc game dùng nhiều bộ nhớ thì lâu hơn (trong thí nghiệm khoảng 150–170 ms). GC của Unity quét toàn bộ heap mỗi lần chạy, nên game đang dùng càng nhiều bộ nhớ thì mỗi lần dừng càng lâu.
Trên đồ thị
Vọt lên theo chu kỳ · Frame time, thời điểm GC chạy
Chỗ cần xem
Marker GC.Collect, GC.Alloc trong Unity Profiler trên bản build development. Với Unreal: stat GC và stat Hitches (ghi log các khung hình vượt ngưỡng đặt bằng t.HitchFrameTimeThreshold)
Đúng nếu
khung hình nào vọt lên cũng có đoạn GC.Collect dài xấp xỉ mức vọt, cách nhau đều đặn vài giây đến vài chục giây. Ở nơi đông người, GC.Alloc mỗi khung hình tăng lên
Loại trừ nếu
khung hình vọt lên không có đoạn GC → xem “Tải đồng bộ trên main thread và biên dịch shader” hoặc “Tải render khi đông người”
Cách kiểm tra
Cần log và chỉ số của server, client game
Tìm hiểu thêm
Hiện tượng này phổ biến ở client viết bằng C# như Unity. Thủ phạm chính là code tạo mới chuỗi log chiến đấu, số sát thương, chữ trên UI ở mỗi khung hình. Nếu chỉ giật ở nơi đông người, nghĩa là có đoạn code sinh rác tăng theo số người. Incremental GC chia việc thu gom thành từng phần nhỏ ở mỗi khung hình (mặc định của Unity là 3 ms), nhưng nếu rác sinh ra nhanh hơn tốc độ thu gom thì cuối cùng game vẫn dừng một lượt. Unreal Engine cũng có GC riêng để dọn các game object không còn dùng. Tùy phiên bản engine và cấu hình, với thiết lập mặc định GC này chạy khoảng 1 phút một lần và có thể gây khựng cách nhau 1 phút. Client viết luật game bằng script như Lua còn có thêm GC riêng của script đó.
Nguồn
Garbage collection modesUnity Incremental GC là mặc định và thu gom rải ra nhiều khung hình; nếu tắt, main thread dừng trong lúc quét toàn bộ heap, có thể tới hàng trăm ms
Profiler markers referenceUnity GC.Collect: khoảng thời gian code chương trình dừng trong lúc thu gom rác (dưới 1 ms đến hàng trăm ms); GC.Alloc: cấp phát trên managed heap
Stat Commands in Unreal EngineEpic Games stat GC (thống kê thu gom rác), stat Hitches (ghi log các khung hình vượt t.HitchFrameTimeThreshold)