한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

游戏卡顿白皮书 › L10 内存

脚本引擎 GC 停顿 Scripting VM GC (Lua, etc.)

原因 ID mem-script-gc · 主责 研发团队·服务器开发

在含图示和实验的完整版中打开此卡片 →

即使是 C++ 服务器,如果任务、AI、技能用 Lua 等脚本来跑,脚本引擎执行 GC 期间,对应的场景也会停住。

起因 每个场景的脚本引擎在执行任务、AI、事件时大量创建临时对象 → 结果 脚本引擎的 GC 一次回收太多时,这个场景的 tick 停住 → 画面表现 只在特定场景、特定事件期间周期性地顿一下

症状
一卡一卡, 卡住
因素
停顿
谁会遇到
特定地点/分线
何时出现
人多的时候, 固定周期
负责方
主责 研发团队·服务器开发
研发团队要做的事
设置增量或分代 GC,每个 tick 推进一小步 GC,减少脚本中的临时对象。
数值参考
脚本堆涨到数百 MB 后,一次性集中回收(关闭增量回收,或分代模式下的完整回收)有时要花几十到几百 ms。
监控图上
周期性尖峰 · 各场景 tick 耗时、脚本引擎内存
查看位置
每个 tick 记录各场景的 tick 耗时和这个场景脚本引擎的内存占用(Lua 用 collectgarbage("count")),叠加在同一张图上对照
确认依据
脚本内存骤降的时刻(一次性集中回收)与这个场景的 tick 冲高重合,其他场景正常
排除依据
脚本内存没有变化却冲高,是这个场景的负载或锁。服务器上所有场景同时冲高,看“服务器 GC 全局停顿”(mem-gc)或“swap”(mem-swap)
确认手段
需要游戏服务器/客户端的日志和指标

出处

  1. Lua 5.4 Reference Manual Lua.org
    增量模式把回收拆成小步,穿插在程序执行之间(步长设得太大就变成全局停顿);分代模式的 major 回收要遍历所有对象,属于全局停顿;collectgarbage("count") 返回 Lua 使用的内存总量(KB)

相关原因

同一层:L10 内存

其他层中同样导致“一卡一卡”的原因

查看含图示和实验的原卡片