遊戲 Lag 白皮書 › L10 記憶體
腳本引擎的 GC 暫停 Scripting VM GC (Lua, etc.)
原因 ID mem-script-gc · 主要負責 遊戲開發團隊(伺服器開發)
在含圖解與實驗的完整版中開啟卡片 →
即使是 C++ 伺服器,只要任務、AI、技能是用 Lua 等腳本執行,腳本引擎進行 GC 的期間,該 zone 就會停住。
為什麼 每個 zone 的腳本引擎執行任務、AI、事件時,大量產生暫時物件 → 於是 腳本引擎的 GC 一次回收大量物件時,該 zone 的 tick 會停住 → 畫面上 只在特定 zone 或特定活動期間週期性地頓一下
- 症狀
- 卡頓, 定格
- 因素
- 停滯
- 誰會遇到
- 特定地點/頻道
- 何時
- 人潮湧入時, 固定週期
- 負責單位
- 主要負責 遊戲開發團隊(伺服器開發)
- 遊戲開發團隊要做的事
- 設定漸進式或分代 GC、每個 tick 只推進一小段 GC、減少腳本產生的暫時物件。
- 數值參考
- 腳本 heap 長到數百 MB 時,一次集中進行的回收(關閉漸進式回收,或分代模式下的完整回收)有時要花數十~數百 ms。
- 圖表上
- 固定週期飆高 · 各 zone 的 tick 時間、腳本引擎記憶體
- 查看位置
- 每個 tick 記錄各 zone 的 tick 時間與該 zone 腳本引擎的記憶體用量(Lua 用 collectgarbage("count")),疊在同一張圖表上看
- 符合的跡象
- 腳本記憶體驟降的瞬間(一次集中回收)與該 zone 的 tick 飆高重疊,其他 zone 正常
- 不符合的跡象
- 腳本記憶體沒有變化卻飆高時,是該 zone 的負載或鎖。伺服器所有 zone 同時飆高時,是伺服器 GC(mem-gc)或 swap(mem-swap)
- 確認方式
- 需要遊戲伺服器/用戶端的 log 與指標
出處
- Lua 5.4 Reference Manual Lua.org
漸進式模式把回收拆成小步驟,穿插在程式執行之間(步驟設得太大就會全面暫停);分代模式的 major 回收會走訪所有物件,屬於全面暫停;collectgarbage("count") 回傳 Lua 使用的記憶體總量(KB)
相關原因
同一層:L10 記憶體
同一症狀(卡頓)在其他層的原因
查看含圖解與實驗的完整版卡片