游戏卡顿白皮书 › L10 内存
内存分配暴增 Allocation storms
原因 ID mem-alloc · 主责 研发团队·服务器开发
在含图示和实验的完整版中打开此卡片 →
活动期间大量创建临时对象,GC 会比平时频繁得多。
起因 物品掉落、战斗日志、活动奖励让临时对象激增 → 结果 GC 频率翻了几倍,还没来得及丢弃的对象晋升到老年代,Full GC 也随之提前 → 画面表现 只在活动期间周期性地顿一下
- 症状
- 一卡一卡, 卡住
- 因素
- 停顿
- 谁会遇到
- 全服, 特定地点/分线
- 何时出现
- 人多的时候
- 负责方
- 主责 研发团队·服务器开发
- 研发团队要做的事
- 对象池,缓冲区复用,用 profiler 分析内存分配。
- 监控图上
- 随人数/负载上升 · GC 次数、分配速率
- 查看位置
- 用 GC 日志(Java -Xlog:gc,Go GODEBUG=gctrace=1)统计每分钟 GC 次数;.NET 看 dotnet-counters 的分配量和 GC 次数(.NET 9 起为 dotnet.gc.heap.total_allocated、dotnet.gc.collections,8 及以下为 Allocation Rate、Gen 0 GC Count)。与同时在线人数、活动时间叠加对照
- 确认依据
- 活动开始后,分配速率和 GC 次数比人数增长得更陡,短停顿变得频繁。活动结束后恢复原状
- 排除依据
- GC 次数不变而单次停顿变长,说明存活数据增加了,看“GC 颠簸(堆余量不足)”(mem-gc-thrash)、“内存泄漏”(mem-leak)
- 确认手段
- 运维工具即可确认(无需游戏代码)
出处
- Garbage Collector Implementation Oracle
新生代满了触发 minor GC,部分存活对象被移到老年代;老年代满了就回收整个堆(比 minor 慢得多);-Xlog:gc 每次 GC 记录一行 - A Guide to the Go Garbage Collector Go
分配速率越高,GC 周期越频繁;用 GODEBUG=gctrace=1 输出 GC 跟踪信息 - dotnet-counters diagnostic tool .NET
.NET 9 起显示为 dotnet.gc.heap.total_allocated、dotnet.gc.collections,.NET 8 及以下显示为 Allocation Rate、Gen 0 GC Count
相关原因
同一层:L10 内存
其他层中同样导致“一卡一卡”的原因
查看含图示和实验的原卡片